commit
6e3e05befc
158 changed files with 4737 additions and 3012 deletions
1
.github/workflows/dependencies.yml
vendored
1
.github/workflows/dependencies.yml
vendored
|
|
@ -19,6 +19,7 @@ env:
|
|||
PR_TITLE: Weekly `cargo update`
|
||||
PR_MESSAGE: |
|
||||
Automation to keep dependencies in `Cargo.lock` current.
|
||||
r? dep-bumps
|
||||
|
||||
The following is the output from `cargo update`:
|
||||
COMMIT_MESSAGE: "cargo update \n\n"
|
||||
|
|
|
|||
17
Cargo.lock
17
Cargo.lock
|
|
@ -581,7 +581,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"syn 2.0.104",
|
||||
"tempfile",
|
||||
"termize",
|
||||
"termize 0.1.1",
|
||||
"tokio",
|
||||
"toml 0.7.8",
|
||||
"ui_test",
|
||||
|
|
@ -3761,7 +3761,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"termcolor",
|
||||
"termize",
|
||||
"termize 0.2.0",
|
||||
"tracing",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
|
@ -4133,6 +4133,7 @@ dependencies = [
|
|||
"rustc_fs_util",
|
||||
"rustc_hir",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_incremental",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
|
|
@ -4522,7 +4523,7 @@ dependencies = [
|
|||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"termize",
|
||||
"termize 0.2.0",
|
||||
"tracing",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
|
@ -5294,6 +5295,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termize"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8da106d1a19c5b9c53c03311936568a0439926a7607815bd3461139cbab1cc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-float-parse"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use rustc_macros::HashStable_Generic;
|
|||
|
||||
use crate::{
|
||||
AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
|
||||
PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants,
|
||||
PointeeInfo, Primitive, Size, Variants,
|
||||
};
|
||||
|
||||
// Explicitly import `Float` to avoid ambiguity with `Primitive::Float`.
|
||||
|
|
@ -115,16 +115,6 @@ impl<'a> Layout<'a> {
|
|||
pub fn unadjusted_abi_align(self) -> Align {
|
||||
self.0.0.unadjusted_abi_align
|
||||
}
|
||||
|
||||
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
|
||||
///
|
||||
/// Currently, that means that the type is pointer-sized, pointer-aligned,
|
||||
/// and has a initialized (non-union), scalar ABI.
|
||||
pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool {
|
||||
self.size() == data_layout.pointer_size
|
||||
&& self.align().abi == data_layout.pointer_align.abi
|
||||
&& matches!(self.backend_repr(), BackendRepr::Scalar(Scalar::Initialized { .. }))
|
||||
}
|
||||
}
|
||||
|
||||
/// The layout of a type, alongside the type itself.
|
||||
|
|
|
|||
|
|
@ -278,12 +278,21 @@ pub enum AttributeKind {
|
|||
/// Represents `#[naked]`
|
||||
Naked(Span),
|
||||
|
||||
/// Represents `#[no_implicit_prelude]`
|
||||
NoImplicitPrelude(Span),
|
||||
|
||||
/// Represents `#[no_mangle]`
|
||||
NoMangle(Span),
|
||||
|
||||
/// Represents `#[non_exhaustive]`
|
||||
NonExhaustive(Span),
|
||||
|
||||
/// Represents `#[optimize(size|speed)]`
|
||||
Optimize(OptimizeAttr, Span),
|
||||
|
||||
/// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint).
|
||||
PassByValue(Span),
|
||||
|
||||
/// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint).
|
||||
PubTransparent(Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -12,39 +12,44 @@ impl AttributeKind {
|
|||
use EncodeCrossCrate::*;
|
||||
|
||||
match self {
|
||||
// tidy-alphabetical-start
|
||||
Align { .. } => No,
|
||||
AllowConstFnUnstable(..) => No,
|
||||
AllowInternalUnstable(..) => Yes,
|
||||
AsPtr(..) => Yes,
|
||||
BodyStability { .. } => No,
|
||||
Cold(..) => No,
|
||||
Confusables { .. } => Yes,
|
||||
ConstContinue(..) => No,
|
||||
ConstStability { .. } => Yes,
|
||||
ConstStabilityIndirect => No,
|
||||
Deprecation { .. } => Yes,
|
||||
DocComment { .. } => Yes,
|
||||
ExportName { .. } => Yes,
|
||||
Inline(..) => No,
|
||||
LinkSection { .. } => No,
|
||||
MacroTransparency(..) => Yes,
|
||||
Repr(..) => No,
|
||||
Stability { .. } => Yes,
|
||||
Cold(..) => No,
|
||||
ConstContinue(..) => No,
|
||||
LinkName { .. } => Yes,
|
||||
LinkSection { .. } => No,
|
||||
LoopMatch(..) => No,
|
||||
MacroTransparency(..) => Yes,
|
||||
MayDangle(..) => No,
|
||||
MustUse { .. } => Yes,
|
||||
Naked(..) => No,
|
||||
NoImplicitPrelude(..) => No,
|
||||
NoMangle(..) => No,
|
||||
NonExhaustive(..) => Yes,
|
||||
Optimize(..) => No,
|
||||
PassByValue(..) => Yes,
|
||||
PubTransparent(..) => Yes,
|
||||
Repr(..) => No,
|
||||
RustcLayoutScalarValidRangeEnd(..) => Yes,
|
||||
RustcLayoutScalarValidRangeStart(..) => Yes,
|
||||
RustcObjectLifetimeDefault => No,
|
||||
SkipDuringMethodDispatch { .. } => No,
|
||||
Stability { .. } => Yes,
|
||||
TargetFeature(..) => No,
|
||||
TrackCaller(..) => Yes,
|
||||
Used { .. } => No,
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,3 +17,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for PubTransparentParser {
|
|||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent;
|
||||
}
|
||||
|
||||
pub(crate) struct PassByValueParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for PassByValueParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_pass_by_value];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ pub(crate) mod link_attrs;
|
|||
pub(crate) mod lint_helpers;
|
||||
pub(crate) mod loop_match;
|
||||
pub(crate) mod must_use;
|
||||
pub(crate) mod no_implicit_prelude;
|
||||
pub(crate) mod non_exhaustive;
|
||||
pub(crate) mod repr;
|
||||
pub(crate) mod rustc_internal;
|
||||
pub(crate) mod semantics;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
|
||||
use crate::context::Stage;
|
||||
|
||||
pub(crate) struct NoImplicitPreludeParser;
|
||||
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for NoImplicitPreludeParser {
|
||||
const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoImplicitPrelude;
|
||||
}
|
||||
13
compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs
Normal file
13
compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
|
||||
use crate::context::Stage;
|
||||
|
||||
pub(crate) struct NonExhaustiveParser;
|
||||
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for NonExhaustiveParser {
|
||||
const PATH: &[Symbol] = &[sym::non_exhaustive];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive;
|
||||
}
|
||||
|
|
@ -23,9 +23,11 @@ use crate::attributes::confusables::ConfusablesParser;
|
|||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
|
||||
use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
|
||||
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||
use crate::attributes::non_exhaustive::NonExhaustiveParser;
|
||||
use crate::attributes::repr::{AlignParser, ReprParser};
|
||||
use crate::attributes::rustc_internal::{
|
||||
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
|
||||
|
|
@ -141,7 +143,10 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<ConstStabilityIndirectParser>>,
|
||||
Single<WithoutArgs<LoopMatchParser>>,
|
||||
Single<WithoutArgs<MayDangleParser>>,
|
||||
Single<WithoutArgs<NoImplicitPreludeParser>>,
|
||||
Single<WithoutArgs<NoMangleParser>>,
|
||||
Single<WithoutArgs<NonExhaustiveParser>>,
|
||||
Single<WithoutArgs<PassByValueParser>>,
|
||||
Single<WithoutArgs<PubTransparentParser>>,
|
||||
Single<WithoutArgs<TrackCallerParser>>,
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -84,19 +84,34 @@ fn codegen_inner(
|
|||
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
|
||||
);
|
||||
|
||||
let data_id = module
|
||||
.declare_data(
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
Linkage::Export,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let mut data = DataDescription::new();
|
||||
data.set_align(1);
|
||||
let val = oom_strategy.should_panic();
|
||||
data.define(Box::new([val]));
|
||||
module.define_data(data_id, &data).unwrap();
|
||||
{
|
||||
let sig = Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: vec![],
|
||||
returns: vec![AbiParam::new(types::I8)],
|
||||
};
|
||||
let func_id = module
|
||||
.declare_function(
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
Linkage::Export,
|
||||
&sig,
|
||||
)
|
||||
.unwrap();
|
||||
let mut ctx = Context::new();
|
||||
ctx.func.signature = sig;
|
||||
{
|
||||
let mut func_ctx = FunctionBuilderContext::new();
|
||||
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
|
||||
|
||||
let block = bcx.create_block();
|
||||
bcx.switch_to_block(block);
|
||||
let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64);
|
||||
bcx.ins().return_(&[value]);
|
||||
bcx.seal_all_blocks();
|
||||
bcx.finalize();
|
||||
}
|
||||
module.define_function(func_id, &mut ctx).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
let sig = Signature {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
|
||||
#[cfg(feature = "master")]
|
||||
use gccjit::{FnAttribute, VarAttribute};
|
||||
use gccjit::FnAttribute;
|
||||
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
|
||||
use rustc_ast::expand::allocator::{
|
||||
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
|
||||
alloc_error_handler_name, default_fn_name, global_fn_name,
|
||||
|
|
@ -71,15 +71,13 @@ pub(crate) unsafe fn codegen(
|
|||
None,
|
||||
);
|
||||
|
||||
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
|
||||
let global = context.new_global(None, GlobalKind::Exported, i8, name);
|
||||
#[cfg(feature = "master")]
|
||||
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
|
||||
tcx.sess.default_visibility(),
|
||||
)));
|
||||
let value = tcx.sess.opts.unstable_opts.oom.should_panic();
|
||||
let value = context.new_rvalue_from_int(i8, value as i32);
|
||||
global.global_set_initializer_rvalue(value);
|
||||
create_const_value_function(
|
||||
tcx,
|
||||
context,
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
i8,
|
||||
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
|
||||
);
|
||||
|
||||
create_wrapper_function(
|
||||
tcx,
|
||||
|
|
@ -91,6 +89,30 @@ pub(crate) unsafe fn codegen(
|
|||
);
|
||||
}
|
||||
|
||||
fn create_const_value_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
context: &Context<'_>,
|
||||
name: &str,
|
||||
output: Type<'_>,
|
||||
value: RValue<'_>,
|
||||
) {
|
||||
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
|
||||
tcx.sess.default_visibility(),
|
||||
)));
|
||||
|
||||
func.add_attribute(FnAttribute::AlwaysInline);
|
||||
|
||||
if tcx.sess.must_emit_unwind_tables() {
|
||||
// TODO(antoyo): emit unwind tables.
|
||||
}
|
||||
|
||||
let block = func.new_block("entry");
|
||||
block.end_with_return(None, value);
|
||||
}
|
||||
|
||||
fn create_wrapper_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
context: &Context<'_>,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
|
|||
|
||||
use crate::builder::SBuilder;
|
||||
use crate::declare::declare_simple_fn;
|
||||
use crate::llvm::{self, False, True, Type};
|
||||
use crate::llvm::{self, False, True, Type, Value};
|
||||
use crate::{SimpleCx, attributes, debuginfo};
|
||||
|
||||
pub(crate) unsafe fn codegen(
|
||||
|
|
@ -73,13 +73,14 @@ pub(crate) unsafe fn codegen(
|
|||
);
|
||||
|
||||
unsafe {
|
||||
// __rust_alloc_error_handler_should_panic
|
||||
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
|
||||
let ll_g = cx.declare_global(&name, i8);
|
||||
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
||||
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
|
||||
let llval = llvm::LLVMConstInt(i8, val as u64, False);
|
||||
llvm::set_initializer(ll_g, llval);
|
||||
// __rust_alloc_error_handler_should_panic_v2
|
||||
create_const_value_function(
|
||||
tcx,
|
||||
&cx,
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
&i8,
|
||||
&llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, False),
|
||||
);
|
||||
|
||||
// __rust_no_alloc_shim_is_unstable_v2
|
||||
create_wrapper_function(
|
||||
|
|
@ -100,6 +101,34 @@ pub(crate) unsafe fn codegen(
|
|||
}
|
||||
}
|
||||
|
||||
fn create_const_value_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
cx: &SimpleCx<'_>,
|
||||
name: &str,
|
||||
output: &Type,
|
||||
value: &Value,
|
||||
) {
|
||||
let ty = cx.type_func(&[], output);
|
||||
let llfn = declare_simple_fn(
|
||||
&cx,
|
||||
name,
|
||||
llvm::CallConv::CCallConv,
|
||||
llvm::UnnamedAddr::Global,
|
||||
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
|
||||
ty,
|
||||
);
|
||||
|
||||
attributes::apply_to_llfn(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
&[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)],
|
||||
);
|
||||
|
||||
let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
|
||||
let mut bx = SBuilder::build(&cx, llbb);
|
||||
bx.ret(value);
|
||||
}
|
||||
|
||||
fn create_wrapper_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
cx: &SimpleCx<'_>,
|
||||
|
|
|
|||
|
|
@ -103,23 +103,25 @@ fn call_simple_intrinsic<'ll, 'tcx>(
|
|||
sym::minnumf64 => ("llvm.minnum", &[bx.type_f64()]),
|
||||
sym::minnumf128 => ("llvm.minnum", &[bx.type_f128()]),
|
||||
|
||||
sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
|
||||
sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
|
||||
sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
|
||||
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
|
||||
// when llvm/llvm-project#{139380,139381,140445} are fixed.
|
||||
//sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
|
||||
//sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
|
||||
//sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
|
||||
//sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
|
||||
//
|
||||
sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]),
|
||||
sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]),
|
||||
sym::maxnumf64 => ("llvm.maxnum", &[bx.type_f64()]),
|
||||
sym::maxnumf128 => ("llvm.maxnum", &[bx.type_f128()]),
|
||||
|
||||
sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
|
||||
sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
|
||||
sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
|
||||
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
|
||||
// when llvm/llvm-project#{139380,139381,140445} are fixed.
|
||||
//sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
|
||||
//sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
|
||||
//sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
|
||||
//sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
|
||||
//
|
||||
sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]),
|
||||
sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]),
|
||||
sym::copysignf64 => ("llvm.copysign", &[bx.type_f64()]),
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ impl SlotIndex {
|
|||
index_in_bucket: idx as usize,
|
||||
};
|
||||
}
|
||||
// SAFETY: We already ruled out idx 0, so `checked_ilog2` can't return `None`.
|
||||
let bucket = unsafe { idx.checked_ilog2().unwrap_unchecked() as usize };
|
||||
// We already ruled out idx 0, so this `ilog2` never panics (and the check optimizes away)
|
||||
let bucket = idx.ilog2() as usize;
|
||||
let entries = 1 << bucket;
|
||||
SlotIndex {
|
||||
bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ rustc_type_ir = { path = "../rustc_type_ir" }
|
|||
serde = { version = "1.0.125", features = [ "derive" ] }
|
||||
serde_json = "1.0.59"
|
||||
termcolor = "1.2.0"
|
||||
termize = "0.1.1"
|
||||
termize = "0.2"
|
||||
tracing = "0.1"
|
||||
# tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -417,6 +417,15 @@ impl DiagInner {
|
|||
self.args = std::mem::take(&mut self.reserved_args);
|
||||
}
|
||||
|
||||
pub fn emitted_at_sub_diag(&self) -> Subdiag {
|
||||
let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
|
||||
Subdiag {
|
||||
level: crate::Level::Note,
|
||||
messages: vec![(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)],
|
||||
span: MultiSpan::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fields used for Hash, and PartialEq trait.
|
||||
fn keys(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width};
|
|||
use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
use tracing::{debug, instrument, trace, warn};
|
||||
|
||||
use crate::diagnostic::DiagLocation;
|
||||
use crate::registry::Registry;
|
||||
use crate::snippet::{
|
||||
Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
|
||||
|
|
@ -505,6 +504,10 @@ impl Emitter for HumanEmitter {
|
|||
fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) {
|
||||
let fluent_args = to_fluent_args(diag.args.iter());
|
||||
|
||||
if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() {
|
||||
diag.children.insert(0, diag.emitted_at_sub_diag());
|
||||
}
|
||||
|
||||
let mut suggestions = diag.suggestions.unwrap_tag();
|
||||
self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
|
||||
|
||||
|
|
@ -523,7 +526,6 @@ impl Emitter for HumanEmitter {
|
|||
&diag.span,
|
||||
&diag.children,
|
||||
&suggestions,
|
||||
self.track_diagnostics.then_some(&diag.emitted_at),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1468,7 +1470,6 @@ impl HumanEmitter {
|
|||
level: &Level,
|
||||
max_line_num_len: usize,
|
||||
is_secondary: bool,
|
||||
emitted_at: Option<&DiagLocation>,
|
||||
is_cont: bool,
|
||||
) -> io::Result<()> {
|
||||
let mut buffer = StyledBuffer::new();
|
||||
|
|
@ -1978,12 +1979,6 @@ impl HumanEmitter {
|
|||
trace!("buffer: {:#?}", buffer.render());
|
||||
}
|
||||
|
||||
if let Some(tracked) = emitted_at {
|
||||
let track = format!("-Ztrack-diagnostics: created at {tracked}");
|
||||
let len = buffer.num_lines();
|
||||
buffer.append(len, &track, Style::NoStyle);
|
||||
}
|
||||
|
||||
// final step: take our styled buffer, render it, then output it
|
||||
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
|
||||
|
||||
|
|
@ -2478,7 +2473,6 @@ impl HumanEmitter {
|
|||
span: &MultiSpan,
|
||||
children: &[Subdiag],
|
||||
suggestions: &[CodeSuggestion],
|
||||
emitted_at: Option<&DiagLocation>,
|
||||
) {
|
||||
let max_line_num_len = if self.ui_testing {
|
||||
ANONYMIZED_LINE_NUM.len()
|
||||
|
|
@ -2495,7 +2489,6 @@ impl HumanEmitter {
|
|||
level,
|
||||
max_line_num_len,
|
||||
false,
|
||||
emitted_at,
|
||||
!children.is_empty()
|
||||
|| suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden),
|
||||
) {
|
||||
|
|
@ -2541,7 +2534,6 @@ impl HumanEmitter {
|
|||
&child.level,
|
||||
max_line_num_len,
|
||||
true,
|
||||
None,
|
||||
!should_close,
|
||||
) {
|
||||
panic!("failed to emit error: {err}");
|
||||
|
|
@ -2561,7 +2553,6 @@ impl HumanEmitter {
|
|||
&Level::Help,
|
||||
max_line_num_len,
|
||||
true,
|
||||
None,
|
||||
// FIXME: this needs to account for the suggestion type,
|
||||
// some don't take any space.
|
||||
i + 1 != suggestions.len(),
|
||||
|
|
|
|||
|
|
@ -372,13 +372,16 @@ impl Diagnostic {
|
|||
};
|
||||
let level = diag.level.to_str();
|
||||
let spans = DiagnosticSpan::from_multispan(&diag.span, &args, je);
|
||||
let children = diag
|
||||
let mut children: Vec<Diagnostic> = diag
|
||||
.children
|
||||
.iter()
|
||||
.map(|c| Diagnostic::from_sub_diagnostic(c, &args, je))
|
||||
.chain(sugg)
|
||||
.collect();
|
||||
|
||||
if je.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() {
|
||||
children
|
||||
.insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je));
|
||||
}
|
||||
let buf = BufWriter::default();
|
||||
let mut dst: Destination = Box::new(buf.clone());
|
||||
let short = je.json_rendered.short();
|
||||
|
|
|
|||
|
|
@ -411,6 +411,15 @@ pub fn compile_declarative_macro(
|
|||
if let Err(e) = p.expect(exp!(FatArrow)) {
|
||||
return dummy_syn_ext(e.emit());
|
||||
}
|
||||
if p.token == token::Eof {
|
||||
let err_sp = p.token.span.shrink_to_hi();
|
||||
let guar = sess
|
||||
.dcx()
|
||||
.struct_span_err(err_sp, "macro definition ended unexpectedly")
|
||||
.with_span_label(err_sp, "expected right-hand side of macro rule")
|
||||
.emit();
|
||||
return dummy_syn_ext(guar);
|
||||
}
|
||||
let rhs_tt = p.parse_token_tree();
|
||||
let rhs_tt = mbe::quoted::parse(
|
||||
&TokenStream::new(vec![rhs_tt]),
|
||||
|
|
|
|||
|
|
@ -367,8 +367,6 @@ language_item_table! {
|
|||
TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None;
|
||||
|
||||
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys;
|
|||
use self::region::region_scope_tree;
|
||||
use crate::{errors, require_c_abi_if_c_variadic};
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
wfcheck::provide(providers);
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]
|
||||
pub(super) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
adt_destructor,
|
||||
adt_async_destructor,
|
||||
|
|
@ -109,6 +109,8 @@ pub fn provide(providers: &mut Providers) {
|
|||
collect_return_position_impl_trait_in_trait_tys,
|
||||
compare_impl_item: compare_impl_item::compare_impl_item,
|
||||
check_coroutine_obligations: check::check_coroutine_obligations,
|
||||
check_type_wf: wfcheck::check_type_wf,
|
||||
check_well_formed: wfcheck::check_well_formed,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt};
|
|||
use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
|
||||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::solve::NoSolution;
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -189,7 +188,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
pub(super) fn check_well_formed(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let mut res = crate::check::check::check_item_type(tcx, def_id);
|
||||
|
||||
for param in &tcx.generics_of(def_id).own_params {
|
||||
|
|
@ -2249,7 +2251,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
|
||||
pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
|
||||
let items = tcx.hir_crate_items(());
|
||||
let res = items
|
||||
.par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))
|
||||
|
|
@ -2397,7 +2399,3 @@ struct RedundantLifetimeArgsLint<'tcx> {
|
|||
// The lifetime we can replace the victim with.
|
||||
candidate: ty::Region<'tcx>,
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { check_type_wf, check_well_formed, ..*providers };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
use rustc_data_structures::unord::{ExtendUnord, UnordSet};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::lint;
|
||||
use tracing::debug;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { check_unused_traits, ..*providers };
|
||||
}
|
||||
|
||||
fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
|
||||
pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
|
||||
let mut used_trait_imports = UnordSet::<LocalDefId>::default();
|
||||
|
||||
// FIXME: Use `tcx.hir_par_body_owners()` when we implement creating `DefId`s
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ pub(super) fn check_trait<'tcx>(
|
|||
checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?;
|
||||
checker
|
||||
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?;
|
||||
checker.check(lang_items.pointer_like(), visit_implementation_of_pointer_like)?;
|
||||
checker.check(
|
||||
lang_items.coerce_pointee_validated_trait(),
|
||||
visit_implementation_of_coerce_pointee_validity,
|
||||
|
|
@ -707,104 +706,6 @@ fn infringing_fields_error<'tcx>(
|
|||
err.emit()
|
||||
}
|
||||
|
||||
fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let tcx = checker.tcx;
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, checker.impl_def_id);
|
||||
let impl_span = tcx.def_span(checker.impl_def_id);
|
||||
let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty();
|
||||
|
||||
let is_permitted_primitive = match *self_ty.kind() {
|
||||
ty::Adt(def, _) => def.is_box(),
|
||||
ty::Uint(..) | ty::Int(..) | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if is_permitted_primitive
|
||||
&& let Ok(layout) = tcx.layout_of(typing_env.as_query_input(self_ty))
|
||||
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let why_disqualified = match *self_ty.kind() {
|
||||
// If an ADT is repr(transparent)
|
||||
ty::Adt(self_ty_def, args) => {
|
||||
if self_ty_def.repr().transparent() {
|
||||
// FIXME(compiler-errors): This should and could be deduplicated into a query.
|
||||
// Find the nontrivial field.
|
||||
let adt_typing_env = ty::TypingEnv::non_body_analysis(tcx, self_ty_def.did());
|
||||
let nontrivial_field = self_ty_def.all_fields().find(|field_def| {
|
||||
let field_ty = tcx.type_of(field_def.did).instantiate_identity();
|
||||
!tcx.layout_of(adt_typing_env.as_query_input(field_ty))
|
||||
.is_ok_and(|layout| layout.layout.is_1zst())
|
||||
});
|
||||
|
||||
if let Some(nontrivial_field) = nontrivial_field {
|
||||
// Check that the nontrivial field implements `PointerLike`.
|
||||
let nontrivial_field_ty = nontrivial_field.ty(tcx, args);
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_bound(
|
||||
ObligationCause::misc(impl_span, checker.impl_def_id),
|
||||
param_env,
|
||||
nontrivial_field_ty,
|
||||
tcx.require_lang_item(LangItem::PointerLike, impl_span),
|
||||
);
|
||||
// FIXME(dyn-star): We should regionck this implementation.
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
return Ok(());
|
||||
} else {
|
||||
format!(
|
||||
"the field `{field_name}` of {descr} `{self_ty}` \
|
||||
does not implement `PointerLike`",
|
||||
field_name = nontrivial_field.name,
|
||||
descr = self_ty_def.descr()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
format!(
|
||||
"the {descr} `{self_ty}` is `repr(transparent)`, \
|
||||
but does not have a non-trivial field (it is zero-sized)",
|
||||
descr = self_ty_def.descr()
|
||||
)
|
||||
}
|
||||
} else if self_ty_def.is_box() {
|
||||
// If we got here, then the `layout.is_pointer_like()` check failed
|
||||
// and this box is not a thin pointer.
|
||||
|
||||
String::from("boxes of dynamically-sized types are too large to be `PointerLike`")
|
||||
} else {
|
||||
format!(
|
||||
"the {descr} `{self_ty}` is not `repr(transparent)`",
|
||||
descr = self_ty_def.descr()
|
||||
)
|
||||
}
|
||||
}
|
||||
ty::Ref(..) => {
|
||||
// If we got here, then the `layout.is_pointer_like()` check failed
|
||||
// and this reference is not a thin pointer.
|
||||
String::from("references to dynamically-sized types are too large to be `PointerLike`")
|
||||
}
|
||||
ty::Dynamic(..) | ty::Foreign(..) => {
|
||||
String::from("types of dynamic or unknown size may not implement `PointerLike`")
|
||||
}
|
||||
_ => {
|
||||
// This is a white lie; it is true everywhere outside the standard library.
|
||||
format!("only user-defined sized types are eligible for `impl PointerLike`")
|
||||
}
|
||||
};
|
||||
|
||||
Err(tcx
|
||||
.dcx()
|
||||
.struct_span_err(
|
||||
impl_span,
|
||||
"implementation must be applied to type that has the same ABI as a pointer, \
|
||||
or is `repr(transparent)` and whose field is `PointerLike`",
|
||||
)
|
||||
.with_note(why_disqualified)
|
||||
.emit())
|
||||
}
|
||||
|
||||
fn visit_implementation_of_coerce_pointee_validity(
|
||||
checker: &Checker<'_>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ fn enforce_empty_impls_for_marker_traits(
|
|||
.emit())
|
||||
}
|
||||
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`].
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
use self::builtin::coerce_unsized_info;
|
||||
use self::inherent_impls::{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ mod type_of;
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
resolve_bound_vars::provide(providers);
|
||||
*providers = Providers {
|
||||
|
|
@ -778,9 +779,11 @@ fn lower_variant<'tcx>(
|
|||
fields,
|
||||
parent_did.to_def_id(),
|
||||
recovered,
|
||||
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
||||
|| variant_did
|
||||
.is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
|
||||
adt_kind == AdtKind::Struct
|
||||
&& find_attr!(tcx.get_all_attrs(parent_did), AttributeKind::NonExhaustive(..))
|
||||
|| variant_did.is_some_and(|variant_did| {
|
||||
find_attr!(tcx.get_all_attrs(variant_did), AttributeKind::NonExhaustive(..))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ enum BinderScopeType {
|
|||
|
||||
type ScopeRef<'a> = &'a Scope<'a>;
|
||||
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
resolve_bound_vars,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind};
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ObligationCause, ObligationCauseCode, WellFormedLoc};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
|
|
@ -12,13 +11,9 @@ use tracing::debug;
|
|||
|
||||
use crate::collect::ItemCtxt;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { diagnostic_hir_wf_check, ..*providers };
|
||||
}
|
||||
|
||||
// Ideally, this would be in `rustc_trait_selection`, but we
|
||||
// need access to `ItemCtxt`
|
||||
fn diagnostic_hir_wf_check<'tcx>(
|
||||
pub(super) fn diagnostic_hir_wf_check<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc),
|
||||
) -> Option<ObligationCause<'tcx>> {
|
||||
|
|
|
|||
|
|
@ -150,18 +150,21 @@ fn require_c_abi_if_c_variadic(
|
|||
.emit();
|
||||
}
|
||||
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
collect::provide(providers);
|
||||
coherence::provide(providers);
|
||||
check::provide(providers);
|
||||
check_unused::provide(providers);
|
||||
variance::provide(providers);
|
||||
outlives::provide(providers);
|
||||
hir_wf_check::provide(providers);
|
||||
*providers = Providers {
|
||||
check_unused_traits: check_unused::check_unused_traits,
|
||||
diagnostic_hir_wf_check: hir_wf_check::diagnostic_hir_wf_check,
|
||||
inferred_outlives_crate: outlives::inferred_outlives_crate,
|
||||
inferred_outlives_of: outlives::inferred_outlives_of,
|
||||
inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
|
||||
enforce_impl_non_lifetime_params_are_constrained:
|
||||
impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
|
||||
crate_variances: variance::crate_variances,
|
||||
variances_of: variance::variances_of,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, CratePredicatesMap, GenericArgKind, TyCtxt, Upcast};
|
||||
use rustc_span::Span;
|
||||
|
||||
|
|
@ -9,11 +8,10 @@ mod explicit;
|
|||
mod implicit_infer;
|
||||
mod utils;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers };
|
||||
}
|
||||
|
||||
fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clause<'_>, Span)] {
|
||||
pub(super) fn inferred_outlives_of(
|
||||
tcx: TyCtxt<'_>,
|
||||
item_def_id: LocalDefId,
|
||||
) -> &[(ty::Clause<'_>, Span)] {
|
||||
match tcx.def_kind(item_def_id) {
|
||||
DefKind::Struct | DefKind::Enum | DefKind::Union => {
|
||||
let crate_map = tcx.inferred_outlives_crate(());
|
||||
|
|
@ -48,7 +46,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
|
|||
}
|
||||
}
|
||||
|
||||
fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
||||
pub(super) fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
||||
// Compute a map from each ADT (struct/enum/union) and lazy type alias to
|
||||
// the **explicit** outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
|
||||
// Typically there won't be many of these, except in older code where
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use rustc_arena::DroplessArena;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{
|
||||
self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||
|
|
@ -27,18 +26,14 @@ mod solve;
|
|||
|
||||
pub(crate) mod dump;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { variances_of, crate_variances, ..*providers };
|
||||
}
|
||||
|
||||
fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> {
|
||||
pub(super) fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> {
|
||||
let arena = DroplessArena::default();
|
||||
let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &arena);
|
||||
let constraints_cx = constraints::add_constraints_from_crate(terms_cx);
|
||||
solve::solve_constraints(constraints_cx)
|
||||
}
|
||||
|
||||
fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
||||
pub(super) fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
||||
// Skip items with no generics - there's nothing to infer in them.
|
||||
if tcx.generics_of(item_def_id).is_empty() {
|
||||
return &[];
|
||||
|
|
|
|||
|
|
@ -536,7 +536,12 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
|
|||
diag.emit()
|
||||
}
|
||||
|
||||
/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
method::provide(providers);
|
||||
*providers = Providers { typeck, used_trait_imports, ..*providers };
|
||||
*providers = Providers {
|
||||
method_autoderef_steps: method::probe::method_autoderef_steps,
|
||||
typeck,
|
||||
used_trait_imports,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace};
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, InferOk};
|
||||
use rustc_infer::traits::PredicateObligations;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt,
|
||||
|
|
@ -28,10 +27,6 @@ pub(crate) use self::MethodError::*;
|
|||
use self::probe::{IsSuggestion, ProbeScope};
|
||||
use crate::FnCtxt;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
probe::provide(providers);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) struct MethodCallee<'tcx> {
|
||||
/// Impl method ID, for inherent methods, or trait method ID, otherwise.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryRespons
|
|||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::elaborate::supertrait_def_ids;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -554,11 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
providers.method_autoderef_steps = method_autoderef_steps;
|
||||
}
|
||||
|
||||
fn method_autoderef_steps<'tcx>(
|
||||
pub(crate) fn method_autoderef_steps<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
goal: CanonicalTyGoal<'tcx>,
|
||||
) -> MethodAutoderefStepsResult<'tcx> {
|
||||
|
|
|
|||
|
|
@ -871,8 +871,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
|
|||
providers.analysis = analysis;
|
||||
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
|
||||
providers.resolver_for_lowering_raw = resolver_for_lowering_raw;
|
||||
providers.stripped_cfg_items =
|
||||
|tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal());
|
||||
providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
|
||||
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
|
||||
providers.early_lint_checks = early_lint_checks;
|
||||
providers.env_var_os = env_var_os;
|
||||
|
|
|
|||
|
|
@ -45,11 +45,24 @@ impl Linker {
|
|||
}
|
||||
|
||||
pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) {
|
||||
let (codegen_results, work_products) = sess.time("finish_ongoing_codegen", || {
|
||||
let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || {
|
||||
codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames)
|
||||
});
|
||||
sess.timings.end_section(sess.dcx(), TimingSection::Codegen);
|
||||
|
||||
if sess.opts.incremental.is_some()
|
||||
&& let Some(path) = self.metadata.path()
|
||||
&& let Some((id, product)) =
|
||||
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
|
||||
sess,
|
||||
"metadata",
|
||||
&[("rmeta", path)],
|
||||
&[],
|
||||
)
|
||||
{
|
||||
work_products.insert(id, product);
|
||||
}
|
||||
|
||||
sess.dcx().abort_if_errors();
|
||||
|
||||
let _timer = sess.timer("link");
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::lints::PassByValueDiag;
|
||||
use crate::{LateContext, LateLintPass, LintContext};
|
||||
|
|
@ -45,14 +45,16 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
|
|||
fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
|
||||
if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
|
||||
match path.res {
|
||||
Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => {
|
||||
Res::Def(_, def_id)
|
||||
if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::PassByValue(_)) =>
|
||||
{
|
||||
let name = cx.tcx.item_ident(def_id);
|
||||
let path_segment = path.segments.last().unwrap();
|
||||
return Some(format!("{}{}", name, gen_args(cx, path_segment)));
|
||||
}
|
||||
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
|
||||
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() {
|
||||
if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
|
||||
if find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::PassByValue(_)) {
|
||||
return Some(cx.tcx.def_path_str_with_args(adt.did(), args));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
|||
rustc_fs_util = { path = "../rustc_fs_util" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
|
||||
rustc_incremental = { path = "../rustc_incremental" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_hir_pretty::id_to_string;
|
||||
use rustc_middle::dep_graph::WorkProductId;
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_middle::middle::exported_symbols::metadata_symbol_name;
|
||||
use rustc_middle::mir::interpret;
|
||||
|
|
@ -2307,6 +2308,8 @@ pub struct EncodedMetadata {
|
|||
// This is an optional stub metadata containing only the crate header.
|
||||
// The header should be very small, so we load it directly into memory.
|
||||
stub_metadata: Option<Vec<u8>>,
|
||||
// The path containing the metadata, to record as work product.
|
||||
path: Option<Box<Path>>,
|
||||
// We need to carry MaybeTempDir to avoid deleting the temporary
|
||||
// directory while accessing the Mmap.
|
||||
_temp_dir: Option<MaybeTempDir>,
|
||||
|
|
@ -2322,14 +2325,24 @@ impl EncodedMetadata {
|
|||
let file = std::fs::File::open(&path)?;
|
||||
let file_metadata = file.metadata()?;
|
||||
if file_metadata.len() == 0 {
|
||||
return Ok(Self { full_metadata: None, stub_metadata: None, _temp_dir: None });
|
||||
return Ok(Self {
|
||||
full_metadata: None,
|
||||
stub_metadata: None,
|
||||
path: None,
|
||||
_temp_dir: None,
|
||||
});
|
||||
}
|
||||
let full_mmap = unsafe { Some(Mmap::map(file)?) };
|
||||
|
||||
let stub =
|
||||
if let Some(stub_path) = stub_path { Some(std::fs::read(stub_path)?) } else { None };
|
||||
|
||||
Ok(Self { full_metadata: full_mmap, stub_metadata: stub, _temp_dir: temp_dir })
|
||||
Ok(Self {
|
||||
full_metadata: full_mmap,
|
||||
stub_metadata: stub,
|
||||
path: Some(path.into()),
|
||||
_temp_dir: temp_dir,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -2341,6 +2354,11 @@ impl EncodedMetadata {
|
|||
pub fn stub_or_full(&self) -> &[u8] {
|
||||
self.stub_metadata.as_deref().unwrap_or(self.full())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn path(&self) -> Option<&Path> {
|
||||
self.path.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for EncodedMetadata {
|
||||
|
|
@ -2365,17 +2383,53 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata {
|
|||
None
|
||||
};
|
||||
|
||||
Self { full_metadata, stub_metadata: stub, _temp_dir: None }
|
||||
Self { full_metadata, stub_metadata: stub, path: None, _temp_dir: None }
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(tcx))]
|
||||
pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
|
||||
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");
|
||||
|
||||
// Since encoding metadata is not in a query, and nothing is cached,
|
||||
// there's no need to do dep-graph tracking for any of it.
|
||||
tcx.dep_graph.assert_ignored();
|
||||
|
||||
// Generate the metadata stub manually, as that is a small file compared to full metadata.
|
||||
if let Some(ref_path) = ref_path {
|
||||
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub");
|
||||
|
||||
with_encode_metadata_header(tcx, ref_path, |ecx| {
|
||||
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
|
||||
name: tcx.crate_name(LOCAL_CRATE),
|
||||
triple: tcx.sess.opts.target_triple.clone(),
|
||||
hash: tcx.crate_hash(LOCAL_CRATE),
|
||||
is_proc_macro_crate: false,
|
||||
is_stub: true,
|
||||
});
|
||||
header.position.get()
|
||||
})
|
||||
}
|
||||
|
||||
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");
|
||||
|
||||
let dep_node = tcx.metadata_dep_node();
|
||||
|
||||
// If the metadata dep-node is green, try to reuse the saved work product.
|
||||
if tcx.dep_graph.is_fully_enabled()
|
||||
&& let work_product_id = WorkProductId::from_cgu_name("metadata")
|
||||
&& let Some(work_product) = tcx.dep_graph.previous_work_product(&work_product_id)
|
||||
&& tcx.try_mark_green(&dep_node)
|
||||
{
|
||||
let saved_path = &work_product.saved_files["rmeta"];
|
||||
let incr_comp_session_dir = tcx.sess.incr_comp_session_dir_opt().unwrap();
|
||||
let source_file = rustc_incremental::in_incr_comp_dir(&incr_comp_session_dir, saved_path);
|
||||
debug!("copying preexisting metadata from {source_file:?} to {path:?}");
|
||||
match rustc_fs_util::link_or_copy(&source_file, path) {
|
||||
Ok(_) => {}
|
||||
Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }),
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
if tcx.sess.threads() != 1 {
|
||||
// Prefetch some queries used by metadata encoding.
|
||||
// This is not necessary for correctness, but is only done for performance reasons.
|
||||
|
|
@ -2389,35 +2443,32 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
|
|||
);
|
||||
}
|
||||
|
||||
with_encode_metadata_header(tcx, path, |ecx| {
|
||||
// Encode all the entries and extra information in the crate,
|
||||
// culminating in the `CrateRoot` which points to all of it.
|
||||
let root = ecx.encode_crate_root();
|
||||
// Perform metadata encoding inside a task, so the dep-graph can check if any encoded
|
||||
// information changes, and maybe reuse the work product.
|
||||
tcx.dep_graph.with_task(
|
||||
dep_node,
|
||||
tcx,
|
||||
path,
|
||||
|tcx, path| {
|
||||
with_encode_metadata_header(tcx, path, |ecx| {
|
||||
// Encode all the entries and extra information in the crate,
|
||||
// culminating in the `CrateRoot` which points to all of it.
|
||||
let root = ecx.encode_crate_root();
|
||||
|
||||
// Flush buffer to ensure backing file has the correct size.
|
||||
ecx.opaque.flush();
|
||||
// Record metadata size for self-profiling
|
||||
tcx.prof.artifact_size(
|
||||
"crate_metadata",
|
||||
"crate_metadata",
|
||||
ecx.opaque.file().metadata().unwrap().len(),
|
||||
);
|
||||
// Flush buffer to ensure backing file has the correct size.
|
||||
ecx.opaque.flush();
|
||||
// Record metadata size for self-profiling
|
||||
tcx.prof.artifact_size(
|
||||
"crate_metadata",
|
||||
"crate_metadata",
|
||||
ecx.opaque.file().metadata().unwrap().len(),
|
||||
);
|
||||
|
||||
root.position.get()
|
||||
});
|
||||
|
||||
if let Some(ref_path) = ref_path {
|
||||
with_encode_metadata_header(tcx, ref_path, |ecx| {
|
||||
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
|
||||
name: tcx.crate_name(LOCAL_CRATE),
|
||||
triple: tcx.sess.opts.target_triple.clone(),
|
||||
hash: tcx.crate_hash(LOCAL_CRATE),
|
||||
is_proc_macro_crate: false,
|
||||
is_stub: true,
|
||||
});
|
||||
header.position.get()
|
||||
});
|
||||
}
|
||||
root.position.get()
|
||||
})
|
||||
},
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
fn with_encode_metadata_header(
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ rustc_with_all_queries!(define_dep_nodes![
|
|||
[] fn TraitSelect() -> (),
|
||||
[] fn CompileCodegenUnit() -> (),
|
||||
[] fn CompileMonoItem() -> (),
|
||||
[] fn Metadata() -> (),
|
||||
]);
|
||||
|
||||
// WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys.
|
||||
|
|
@ -115,6 +116,12 @@ pub(crate) fn make_compile_mono_item<'tcx>(
|
|||
DepNode::construct(tcx, dep_kinds::CompileMonoItem, mono_item)
|
||||
}
|
||||
|
||||
// WARNING: `construct` is generic and does not know that `Metadata` takes `()`s as keys.
|
||||
// Be very careful changing this type signature!
|
||||
pub(crate) fn make_metadata(tcx: TyCtxt<'_>) -> DepNode {
|
||||
DepNode::construct(tcx, dep_kinds::Metadata, &())
|
||||
}
|
||||
|
||||
pub trait DepNodeExt: Sized {
|
||||
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::ty::{self, TyCtxt};
|
|||
mod dep_node;
|
||||
|
||||
pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kinds, label_strs};
|
||||
pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item};
|
||||
pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata};
|
||||
pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter};
|
||||
pub use rustc_query_system::dep_graph::{
|
||||
DepContext, DepGraphQuery, DepNodeIndex, Deps, SerializedDepGraph, SerializedDepNodeIndex,
|
||||
|
|
|
|||
|
|
@ -195,7 +195,6 @@ rustc_queries! {
|
|||
}
|
||||
|
||||
query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt {
|
||||
no_hash
|
||||
desc { "getting the resolver outputs" }
|
||||
}
|
||||
|
||||
|
|
@ -2265,9 +2264,6 @@ rustc_queries! {
|
|||
query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
|
||||
desc { "fetching potentially unused trait imports" }
|
||||
}
|
||||
query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxIndexSet<Symbol> {
|
||||
desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
query stability_index(_: ()) -> &'tcx stability::Index {
|
||||
arena_cache
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std::ops::Range;
|
|||
use std::str;
|
||||
|
||||
use rustc_abi::{FIRST_VARIANT, ReprOptions, VariantIdx};
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
|
|
@ -278,7 +279,9 @@ impl AdtDefData {
|
|||
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
|
||||
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
||||
|
||||
if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
|
||||
if kind == AdtKind::Enum
|
||||
&& find_attr!(tcx.get_all_attrs(did), AttributeKind::NonExhaustive(..))
|
||||
{
|
||||
debug!("found non-exhaustive variant list for {:?}", did);
|
||||
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2058,9 +2058,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
|
||||
// Create a dependency to the red node to be sure we re-execute this when the amount of
|
||||
// definitions change.
|
||||
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
|
||||
// Depend on the `analysis` query to ensure compilation if finished.
|
||||
self.ensure_ok().analysis(());
|
||||
|
||||
let definitions = &self.untracked.definitions;
|
||||
gen {
|
||||
|
|
@ -2080,9 +2079,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
|
||||
// Create a dependency to the crate to be sure we re-execute this when the amount of
|
||||
// definitions change.
|
||||
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
|
||||
// Depend on the `analysis` query to ensure compilation if finished.
|
||||
self.ensure_ok().analysis(());
|
||||
|
||||
// Freeze definitions once we start iterating on them, to prevent adding new ones
|
||||
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
|
||||
|
|
@ -3366,6 +3364,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self.resolver_for_lowering_raw(()).0
|
||||
}
|
||||
|
||||
pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
|
||||
crate::dep_graph::make_metadata(self)
|
||||
}
|
||||
|
||||
/// Given an `impl_id`, return the trait it implements.
|
||||
/// Return `None` if this is an inherent impl.
|
||||
pub fn impl_trait_ref(
|
||||
|
|
@ -3415,10 +3417,6 @@ pub struct DeducedParamAttrs {
|
|||
pub fn provide(providers: &mut Providers) {
|
||||
providers.maybe_unused_trait_imports =
|
||||
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
|
||||
providers.names_imported_by_glob_use = |tcx, id| {
|
||||
tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
|
||||
};
|
||||
|
||||
providers.extern_mod_stmt_cnum =
|
||||
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
|
||||
providers.is_panic_runtime =
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
|||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::{Diag, ErrorGuaranteed};
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
|
|
@ -176,11 +176,11 @@ pub struct ResolverOutputs {
|
|||
pub ast_lowering: ResolverAstLowering,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, HashStable)]
|
||||
pub struct ResolverGlobalCtxt {
|
||||
pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
|
||||
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
|
||||
pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
|
||||
pub expn_that_defined: UnordMap<LocalDefId, ExpnId>,
|
||||
pub effective_visibilities: EffectiveVisibilities,
|
||||
pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
|
||||
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
|
||||
|
|
@ -196,8 +196,8 @@ pub struct ResolverGlobalCtxt {
|
|||
pub confused_type_with_std_module: FxIndexMap<Span, Span>,
|
||||
pub doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
|
||||
pub doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
|
||||
pub all_macro_rules: FxHashSet<Symbol>,
|
||||
pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
|
||||
pub all_macro_rules: UnordSet<Symbol>,
|
||||
pub stripped_cfg_items: Vec<StrippedCfgItem>,
|
||||
}
|
||||
|
||||
/// Resolutions that should only be used for lowering.
|
||||
|
|
@ -243,7 +243,7 @@ pub struct DelegationFnSig {
|
|||
pub target_feature: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, HashStable)]
|
||||
pub struct MainDefinition {
|
||||
pub res: Res<ast::NodeId>,
|
||||
pub is_import: bool,
|
||||
|
|
@ -1149,12 +1149,16 @@ impl<'tcx> TypingEnv<'tcx> {
|
|||
{
|
||||
// FIXME(#132279): We should assert that the value does not contain any placeholders
|
||||
// as these placeholders are also local to the current inference context. However, we
|
||||
// currently use pseudo-canonical queries in the trait solver which replaces params with
|
||||
// placeholders. We should also simply not use pseudo-canonical queries in the trait
|
||||
// solver, at which point we can readd this assert. As of writing this comment, this is
|
||||
// only used by `fn layout_is_pointer_like` when calling `layout_of`.
|
||||
// currently use pseudo-canonical queries in the trait solver, which replaces params
|
||||
// with placeholders during canonicalization. We should also simply not use pseudo-
|
||||
// canonical queries in the trait solver, at which point we can readd this assert.
|
||||
//
|
||||
// debug_assert!(!value.has_placeholders());
|
||||
// As of writing this comment, this is only used when normalizing consts that mention
|
||||
// params.
|
||||
/* debug_assert!(
|
||||
!value.has_placeholders(),
|
||||
"{value:?} which has placeholder shouldn't be pseudo-canonicalized"
|
||||
); */
|
||||
PseudoCanonicalInput { typing_env: self, value }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,9 +319,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
}
|
||||
PatKind::Deref { subpattern }
|
||||
}
|
||||
hir::PatKind::Box(subpattern) => {
|
||||
PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
|
||||
}
|
||||
hir::PatKind::Box(subpattern) => PatKind::DerefPattern {
|
||||
subpattern: self.lower_pattern(subpattern),
|
||||
borrow: hir::ByRef::No,
|
||||
},
|
||||
|
||||
hir::PatKind::Slice(prefix, slice, suffix) => {
|
||||
self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix)
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ fn emit_malformed_attribute(
|
|||
| sym::rustc_force_inline
|
||||
| sym::rustc_confusables
|
||||
| sym::rustc_skip_during_method_dispatch
|
||||
| sym::rustc_pass_by_value
|
||||
| sym::repr
|
||||
| sym::align
|
||||
| sym::deprecated
|
||||
|
|
@ -302,6 +303,7 @@ fn emit_malformed_attribute(
|
|||
| sym::rustc_allow_const_fn_unstable
|
||||
| sym::naked
|
||||
| sym::no_mangle
|
||||
| sym::non_exhaustive
|
||||
| sym::must_use
|
||||
| sym::track_caller
|
||||
| sym::link_name
|
||||
|
|
@ -310,6 +312,7 @@ fn emit_malformed_attribute(
|
|||
| sym::link_section
|
||||
| sym::rustc_layout_scalar_valid_range_start
|
||||
| sym::rustc_layout_scalar_valid_range_end
|
||||
| sym::no_implicit_prelude
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,9 +183,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::Naked(attr_span)) => {
|
||||
self.check_naked(hir_id, *attr_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::NoImplicitPrelude(attr_span)) => self
|
||||
.check_generic_attr(
|
||||
hir_id,
|
||||
sym::no_implicit_prelude,
|
||||
*attr_span,
|
||||
target,
|
||||
Target::Mod,
|
||||
),
|
||||
Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => {
|
||||
self.check_track_caller(hir_id, *attr_span, attrs, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::NonExhaustive(attr_span)) => {
|
||||
self.check_non_exhaustive(hir_id, *attr_span, span, target, item)
|
||||
}
|
||||
Attribute::Parsed(
|
||||
AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
|
||||
| AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
|
||||
|
|
@ -213,6 +224,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => {
|
||||
self.check_used(*attr_span, target, span);
|
||||
}
|
||||
&Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => {
|
||||
self.check_pass_by_value(attr_span, span, target)
|
||||
}
|
||||
Attribute::Unparsed(attr_item) => {
|
||||
style = Some(attr_item.style);
|
||||
match attr.path().as_slice() {
|
||||
|
|
@ -226,7 +240,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::no_sanitize, ..] => {
|
||||
self.check_no_sanitize(attr, span, target)
|
||||
}
|
||||
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item),
|
||||
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
||||
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
|
||||
[sym::doc, ..] => self.check_doc_attrs(
|
||||
|
|
@ -275,7 +288,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target),
|
||||
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
|
||||
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
|
||||
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
|
||||
[sym::rustc_allow_incoherent_impl, ..] => {
|
||||
self.check_allow_incoherent_impl(attr, span, target)
|
||||
}
|
||||
|
|
@ -289,16 +301,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
self.check_macro_use(hir_id, attr, target)
|
||||
}
|
||||
[sym::path, ..] => self.check_generic_attr(hir_id, attr, target, Target::Mod),
|
||||
[sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod),
|
||||
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
|
||||
[sym::ignore, ..] | [sym::should_panic, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Fn)
|
||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
|
||||
}
|
||||
[sym::automatically_derived, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Impl)
|
||||
}
|
||||
[sym::no_implicit_prelude, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Mod)
|
||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl)
|
||||
}
|
||||
[sym::proc_macro, ..] => {
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike)
|
||||
|
|
@ -307,7 +316,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute);
|
||||
}
|
||||
[sym::proc_macro_derive, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Fn);
|
||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn);
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
|
||||
}
|
||||
[sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
|
||||
|
|
@ -616,7 +625,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_generic_attr(
|
||||
/// FIXME: Remove when all attributes are ported to the new parser
|
||||
fn check_generic_attr_unparsed(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
|
|
@ -639,6 +649,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_generic_attr(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr_name: Symbol,
|
||||
attr_span: Span,
|
||||
target: Target,
|
||||
allowed_target: Target,
|
||||
) {
|
||||
if target != allowed_target {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr_span,
|
||||
errors::OnlyHasEffectOn {
|
||||
attr_name: attr_name.to_string(),
|
||||
target_name: allowed_target.name().replace(' ', "_"),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `#[naked]` is applied to a function definition.
|
||||
fn check_naked(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
|
||||
match target {
|
||||
|
|
@ -750,7 +781,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_non_exhaustive(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
item: Option<ItemLike<'_>>,
|
||||
|
|
@ -765,7 +796,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
&& fields.iter().any(|f| f.default.is_some())
|
||||
{
|
||||
self.dcx().emit_err(errors::NonExhaustiveWithDefaultFieldValues {
|
||||
attr_span: attr.span(),
|
||||
attr_span,
|
||||
defn_span: span,
|
||||
});
|
||||
}
|
||||
|
|
@ -776,13 +807,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "non_exhaustive");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::NonExhaustiveWrongLocation {
|
||||
attr_span: attr.span(),
|
||||
defn_span: span,
|
||||
});
|
||||
self.dcx()
|
||||
.emit_err(errors::NonExhaustiveWrongLocation { attr_span, defn_span: span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1438,11 +1467,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
|
||||
/// Warns against some misuses of `#[pass_by_value]`
|
||||
fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) {
|
||||
fn check_pass_by_value(&self, attr_span: Span, span: Span, target: Target) {
|
||||
match target {
|
||||
Target::Struct | Target::Enum | Target::TyAlias => {}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::PassByValue { attr_span: attr.span(), span });
|
||||
self.dcx().emit_err(errors::PassByValue { attr_span, span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,27 +221,19 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let slice = match ctor {
|
||||
Struct | Variant(_) | UnionField => match ty.kind() {
|
||||
ty::Tuple(fs) => reveal_and_alloc(cx, fs.iter()),
|
||||
ty::Adt(adt, args) => {
|
||||
if adt.is_box() {
|
||||
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
||||
// patterns. If we're here we can assume this is a box pattern.
|
||||
reveal_and_alloc(cx, once(args.type_at(0)))
|
||||
} else {
|
||||
let variant =
|
||||
&adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
|
||||
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
|
||||
let is_visible =
|
||||
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
|
||||
let is_uninhabited = cx.is_uninhabited(*ty);
|
||||
let is_unstable =
|
||||
cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
|
||||
stab.is_unstable() && stab.feature != sym::rustc_private
|
||||
});
|
||||
let skip = is_uninhabited && (!is_visible || is_unstable);
|
||||
(ty, PrivateUninhabitedField(skip))
|
||||
ty::Adt(adt, _) => {
|
||||
let variant = &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
|
||||
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
|
||||
let is_visible =
|
||||
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
|
||||
let is_uninhabited = cx.is_uninhabited(*ty);
|
||||
let is_unstable = cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
|
||||
stab.is_unstable() && stab.feature != sym::rustc_private
|
||||
});
|
||||
cx.dropless_arena.alloc_from_iter(tys)
|
||||
}
|
||||
let skip = is_uninhabited && (!is_visible || is_unstable);
|
||||
(ty, PrivateUninhabitedField(skip))
|
||||
});
|
||||
cx.dropless_arena.alloc_from_iter(tys)
|
||||
}
|
||||
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
|
||||
},
|
||||
|
|
@ -273,14 +265,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
Struct | Variant(_) | UnionField => match ty.kind() {
|
||||
ty::Tuple(fs) => fs.len(),
|
||||
ty::Adt(adt, ..) => {
|
||||
if adt.is_box() {
|
||||
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
||||
// patterns. If we're here we can assume this is a box pattern.
|
||||
1
|
||||
} else {
|
||||
let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt);
|
||||
adt.variant(variant_idx).fields.len()
|
||||
}
|
||||
let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt);
|
||||
adt.variant(variant_idx).fields.len()
|
||||
}
|
||||
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
|
||||
},
|
||||
|
|
@ -470,8 +456,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
fields = vec![self.lower_pat(subpattern).at_index(0)];
|
||||
arity = 1;
|
||||
ctor = match ty.kind() {
|
||||
// This is a box pattern.
|
||||
ty::Adt(adt, ..) if adt.is_box() => Struct,
|
||||
ty::Ref(..) => Ref,
|
||||
_ => span_bug!(
|
||||
pat.span,
|
||||
|
|
@ -501,28 +485,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
.map(|ipat| self.lower_pat(&ipat.pattern).at_index(ipat.field.index()))
|
||||
.collect();
|
||||
}
|
||||
ty::Adt(adt, _) if adt.is_box() => {
|
||||
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
||||
// patterns. If we're here we can assume this is a box pattern.
|
||||
// FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_,
|
||||
// _)` or a box pattern. As a hack to avoid an ICE with the former, we
|
||||
// ignore other fields than the first one. This will trigger an error later
|
||||
// anyway.
|
||||
// See https://github.com/rust-lang/rust/issues/82772,
|
||||
// explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977
|
||||
// The problem is that we can't know from the type whether we'll match
|
||||
// normally or through box-patterns. We'll have to figure out a proper
|
||||
// solution when we introduce generalized deref patterns. Also need to
|
||||
// prevent mixing of those two options.
|
||||
let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
|
||||
if let Some(pat) = pattern {
|
||||
fields = vec![self.lower_pat(&pat.pattern).at_index(0)];
|
||||
} else {
|
||||
fields = vec![];
|
||||
}
|
||||
ctor = Struct;
|
||||
arity = 1;
|
||||
}
|
||||
ty::Adt(adt, _) => {
|
||||
ctor = match pat.kind {
|
||||
PatKind::Leaf { .. } if adt.is_union() => UnionField,
|
||||
|
|
@ -825,11 +787,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
Bool(b) => b.to_string(),
|
||||
Str(s) => s.to_string(),
|
||||
IntRange(range) => return self.print_pat_range(range, *pat.ty()),
|
||||
Struct if pat.ty().is_box() => {
|
||||
// Outside of the `alloc` crate, the only way to create a struct pattern
|
||||
// of type `Box` is to use a `box` pattern via #[feature(box_patterns)].
|
||||
format!("box {}", print(&pat.fields[0]))
|
||||
}
|
||||
Struct | Variant(_) | UnionField => {
|
||||
let enum_info = match *pat.ty().kind() {
|
||||
ty::Adt(adt_def, _) if adt_def.is_enum() => EnumInfo::Enum {
|
||||
|
|
@ -866,6 +823,14 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap();
|
||||
s
|
||||
}
|
||||
DerefPattern(_) if pat.ty().is_box() && !self.tcx.features().deref_patterns() => {
|
||||
// FIXME(deref_patterns): Remove this special handling once `box_patterns` is gone.
|
||||
// HACK(@dianne): `box _` syntax is exposed on stable in diagnostics, e.g. to
|
||||
// witness non-exhaustiveness of `match Box::new(0) { Box { .. } if false => {} }`.
|
||||
// To avoid changing diagnostics before deref pattern syntax is finalized, let's use
|
||||
// `box _` syntax unless `deref_patterns` is enabled.
|
||||
format!("box {}", print(&pat.fields[0]))
|
||||
}
|
||||
DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])),
|
||||
Slice(slice) => {
|
||||
let (prefix_len, has_dot_dot) = match slice.kind {
|
||||
|
|
@ -964,12 +929,8 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
|
|||
ty: &Self::Ty,
|
||||
) -> fmt::Result {
|
||||
if let ty::Adt(adt, _) = ty.kind() {
|
||||
if adt.is_box() {
|
||||
write!(f, "Box")?
|
||||
} else {
|
||||
let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt));
|
||||
write!(f, "{}", variant.name)?;
|
||||
}
|
||||
let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt));
|
||||
write!(f, "{}", variant.name)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -923,6 +923,17 @@ macro_rules! define_queries {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn Metadata<'tcx>() -> DepKindStruct<'tcx> {
|
||||
DepKindStruct {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Metadata",
|
||||
}
|
||||
}
|
||||
|
||||
$(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
|
||||
$crate::plumbing::query_callback::<query_impl::$name::QueryType<'tcx>>(
|
||||
is_anon!([$($modifiers)*]),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_ast::{
|
|||
self as ast, CRATE_NODE_ID, Crate, ItemKind, MetaItemInner, MetaItemKind, ModKind, NodeId, Path,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr_data_structures::{self as attr, Stability};
|
||||
use rustc_attr_data_structures::{self as attr, AttributeKind, Stability, find_attr};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::codes::*;
|
||||
|
|
@ -1998,9 +1998,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// Otherwise, point out if the struct has any private fields.
|
||||
if let Some(def_id) = res.opt_def_id()
|
||||
&& !def_id.is_local()
|
||||
&& let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive)
|
||||
&& let Some(attr_span) = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::NonExhaustive(span) => *span)
|
||||
{
|
||||
non_exhaustive = Some(attr.span());
|
||||
non_exhaustive = Some(attr_span);
|
||||
} else if let Some(span) = ctor_fields_span {
|
||||
let label = errors::ConstructorPrivateIfAnyFieldPrivate { span };
|
||||
err.subdiagnostic(label);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
|||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::FreezeReadGuard;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed};
|
||||
use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
|
||||
use rustc_feature::BUILTIN_ATTRIBUTES;
|
||||
|
|
@ -1031,7 +1031,7 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
|
||||
expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
|
||||
expn_that_defined: UnordMap<LocalDefId, ExpnId>,
|
||||
|
||||
graph_root: Module<'ra>,
|
||||
|
||||
|
|
@ -1208,7 +1208,7 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
effective_visibilities: EffectiveVisibilities,
|
||||
doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
|
||||
doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
|
||||
all_macro_rules: FxHashSet<Symbol>,
|
||||
all_macro_rules: UnordSet<Symbol>,
|
||||
|
||||
/// Invocation ids of all glob delegations.
|
||||
glob_delegation_invoc_ids: FxHashSet<LocalExpnId>,
|
||||
|
|
@ -1653,16 +1653,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let confused_type_with_std_module = self.confused_type_with_std_module;
|
||||
let effective_visibilities = self.effective_visibilities;
|
||||
|
||||
let stripped_cfg_items = Steal::new(
|
||||
self.stripped_cfg_items
|
||||
.into_iter()
|
||||
.filter_map(|item| {
|
||||
let parent_module =
|
||||
self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id();
|
||||
Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg })
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
let stripped_cfg_items = self
|
||||
.stripped_cfg_items
|
||||
.into_iter()
|
||||
.filter_map(|item| {
|
||||
let parent_module =
|
||||
self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id();
|
||||
Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg })
|
||||
})
|
||||
.collect();
|
||||
|
||||
let global_ctxt = ResolverGlobalCtxt {
|
||||
expn_that_defined,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ rustc_macros = { path = "../rustc_macros" }
|
|||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
termize = "0.1.1"
|
||||
termize = "0.2"
|
||||
tracing = "0.1"
|
||||
# tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -3340,7 +3340,7 @@ pub enum OomStrategy {
|
|||
}
|
||||
|
||||
impl OomStrategy {
|
||||
pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic";
|
||||
pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2";
|
||||
|
||||
pub fn should_panic(self) -> u8 {
|
||||
match self {
|
||||
|
|
|
|||
|
|
@ -4,28 +4,17 @@
|
|||
//! until stable MIR is complete.
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Index;
|
||||
|
||||
use rustc_data_structures::fx;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_middle::mir::interpret::AllocId;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::{CrateNum, DefId};
|
||||
use rustc_span::def_id::CrateNum;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
use stable_mir::Error;
|
||||
use stable_mir::abi::Layout;
|
||||
use stable_mir::compiler_interface::SmirInterface;
|
||||
use stable_mir::ty::IndexedVal;
|
||||
use stable_mir::unstable::{RustcInternal, Stable};
|
||||
|
||||
use crate::rustc_smir::context::SmirCtxt;
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::rustc_smir::{Bridge, SmirContainer, Tables};
|
||||
use crate::stable_mir;
|
||||
|
||||
mod internal;
|
||||
pub mod pretty;
|
||||
|
||||
/// Convert an internal Rust compiler item into its stable counterpart, if one exists.
|
||||
|
|
@ -40,7 +29,7 @@ pub mod pretty;
|
|||
///
|
||||
/// This function will panic if StableMIR has not been properly initialized.
|
||||
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
||||
with_tables(|tables| item.stable(tables))
|
||||
with_container(|tables, cx| item.stable(tables, cx))
|
||||
}
|
||||
|
||||
/// Convert a stable item into its internal Rust compiler counterpart, if one exists.
|
||||
|
|
@ -59,134 +48,9 @@ where
|
|||
S: RustcInternal,
|
||||
{
|
||||
// The tcx argument ensures that the item won't outlive the type context.
|
||||
with_tables(|tables| item.internal(tables, tcx))
|
||||
}
|
||||
|
||||
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
||||
type Output = DefId;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, index: stable_mir::DefId) -> &Self::Output {
|
||||
&self.def_ids[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
|
||||
type Output = Span;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
|
||||
&self.spans[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Tables<'tcx> {
|
||||
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
|
||||
stable_mir::CrateItem(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn adt_def(&mut self, did: DefId) -> stable_mir::ty::AdtDef {
|
||||
stable_mir::ty::AdtDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn foreign_module_def(&mut self, did: DefId) -> stable_mir::ty::ForeignModuleDef {
|
||||
stable_mir::ty::ForeignModuleDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef {
|
||||
stable_mir::ty::ForeignDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn fn_def(&mut self, did: DefId) -> stable_mir::ty::FnDef {
|
||||
stable_mir::ty::FnDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn closure_def(&mut self, did: DefId) -> stable_mir::ty::ClosureDef {
|
||||
stable_mir::ty::ClosureDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineDef {
|
||||
stable_mir::ty::CoroutineDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_closure_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineClosureDef {
|
||||
stable_mir::ty::CoroutineClosureDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef {
|
||||
stable_mir::ty::AliasDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn param_def(&mut self, did: DefId) -> stable_mir::ty::ParamDef {
|
||||
stable_mir::ty::ParamDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn br_named_def(&mut self, did: DefId) -> stable_mir::ty::BrNamedDef {
|
||||
stable_mir::ty::BrNamedDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef {
|
||||
stable_mir::ty::TraitDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
|
||||
stable_mir::ty::GenericDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
|
||||
stable_mir::ty::ConstDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn impl_def(&mut self, did: DefId) -> stable_mir::ty::ImplDef {
|
||||
stable_mir::ty::ImplDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
|
||||
stable_mir::ty::RegionDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_witness_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineWitnessDef {
|
||||
stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn assoc_def(&mut self, did: DefId) -> stable_mir::ty::AssocDef {
|
||||
stable_mir::ty::AssocDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn opaque_def(&mut self, did: DefId) -> stable_mir::ty::OpaqueDef {
|
||||
stable_mir::ty::OpaqueDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
|
||||
stable_mir::ty::Prov(self.create_alloc_id(aid))
|
||||
}
|
||||
|
||||
pub(crate) fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
|
||||
self.def_ids.create_or_fetch(did)
|
||||
}
|
||||
|
||||
pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
|
||||
self.alloc_ids.create_or_fetch(aid)
|
||||
}
|
||||
|
||||
pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
|
||||
self.spans.create_or_fetch(span)
|
||||
}
|
||||
|
||||
pub(crate) fn instance_def(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
) -> stable_mir::mir::mono::InstanceDef {
|
||||
self.instances.create_or_fetch(instance)
|
||||
}
|
||||
|
||||
pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef {
|
||||
stable_mir::mir::mono::StaticDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub(crate) fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> Layout {
|
||||
self.layouts.create_or_fetch(layout)
|
||||
}
|
||||
// See https://github.com/rust-lang/rust/pull/120128/commits/9aace6723572438a94378451793ca37deb768e72
|
||||
// for more details.
|
||||
with_container(|tables, _| item.internal(tables, tcx))
|
||||
}
|
||||
|
||||
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
||||
|
|
@ -197,25 +61,28 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
|||
// datastructures and stable MIR datastructures
|
||||
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||
|
||||
pub(crate) fn init<'tcx, F, T>(cx: &SmirCtxt<'tcx>, f: F) -> T
|
||||
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &SmirContainer<'tcx, B>, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
assert!(!TLV.is_set());
|
||||
let ptr = cx as *const _ as *const ();
|
||||
let ptr = container as *const _ as *const ();
|
||||
TLV.set(&Cell::new(ptr), || f())
|
||||
}
|
||||
|
||||
/// Loads the current context and calls a function with it.
|
||||
/// Do not nest these, as that will ICE.
|
||||
pub(crate) fn with_tables<R>(f: impl for<'tcx> FnOnce(&mut Tables<'tcx>) -> R) -> R {
|
||||
pub(crate) fn with_container<R, B: Bridge>(
|
||||
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
|
||||
) -> R {
|
||||
assert!(TLV.is_set());
|
||||
TLV.with(|tlv| {
|
||||
let ptr = tlv.get();
|
||||
assert!(!ptr.is_null());
|
||||
let context = ptr as *const SmirCtxt<'_>;
|
||||
let mut tables = unsafe { (*context).0.borrow_mut() };
|
||||
f(&mut *tables)
|
||||
let container = ptr as *const SmirContainer<'_, B>;
|
||||
let mut tables = unsafe { (*container).tables.borrow_mut() };
|
||||
let cx = unsafe { (*container).cx.borrow() };
|
||||
f(&mut *tables, &*cx)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -223,23 +90,10 @@ pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
|
|||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let tables = SmirCtxt(RefCell::new(Tables {
|
||||
tcx,
|
||||
def_ids: IndexMap::default(),
|
||||
alloc_ids: IndexMap::default(),
|
||||
spans: IndexMap::default(),
|
||||
types: IndexMap::default(),
|
||||
instances: IndexMap::default(),
|
||||
ty_consts: IndexMap::default(),
|
||||
mir_consts: IndexMap::default(),
|
||||
layouts: IndexMap::default(),
|
||||
}));
|
||||
let smir_cx = RefCell::new(SmirCtxt::new(tcx));
|
||||
let container = SmirContainer { tables: RefCell::new(Tables::default()), cx: smir_cx };
|
||||
|
||||
let interface = SmirInterface { cx: tables };
|
||||
|
||||
// Pass the `SmirInterface` to compiler_interface::run
|
||||
// and initialize the rustc-specific TLS with tables.
|
||||
stable_mir::compiler_interface::run(&interface, || init(&interface.cx, f))
|
||||
stable_mir::compiler_interface::run(&container, || init(&container, f))
|
||||
}
|
||||
|
||||
/// Instantiate and run the compiler with the provided arguments and callback.
|
||||
|
|
@ -417,43 +271,3 @@ macro_rules! run_driver {
|
|||
StableMir::new($callback).run($args)
|
||||
}};
|
||||
}
|
||||
|
||||
/// Similar to rustc's `FxIndexMap`, `IndexMap` with extra
|
||||
/// safety features added.
|
||||
pub struct IndexMap<K, V> {
|
||||
index_map: fx::FxIndexMap<K, V>,
|
||||
}
|
||||
|
||||
impl<K, V> Default for IndexMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self { index_map: FxIndexMap::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> {
|
||||
pub fn create_or_fetch(&mut self, key: K) -> V {
|
||||
let len = self.index_map.len();
|
||||
let v = self.index_map.entry(key).or_insert(V::to_val(len));
|
||||
*v
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V>
|
||||
for IndexMap<K, V>
|
||||
{
|
||||
type Output = K;
|
||||
|
||||
fn index(&self, index: V) -> &Self::Output {
|
||||
let (k, v) = self.index_map.get_index(index.to_index()).unwrap();
|
||||
assert_eq!(*v, index, "Provided value doesn't match with indexed value");
|
||||
k
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait used to translate a stable construct to its rustc counterpart.
|
||||
///
|
||||
/// This is basically a mirror of [crate::rustc_smir::Stable].
|
||||
pub trait RustcInternal {
|
||||
type T<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,102 +1,82 @@
|
|||
use rustc_abi::{Align, Size};
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::{AllocInit, AllocRange, Pointer, alloc_range};
|
||||
use stable_mir::Error;
|
||||
use stable_mir::mir::Mutability;
|
||||
use stable_mir::ty::{Allocation, ProvenanceMap};
|
||||
//! Internal memory allocator implementation for StableMIR.
|
||||
//!
|
||||
//! This module handles all direct interactions with rustc queries and performs
|
||||
//! the actual memory allocations. The stable interface in `stable_mir::alloc`
|
||||
//! delegates all query-related operations to this implementation.
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::stable_mir;
|
||||
use rustc_abi::{Size, TyAndLayout};
|
||||
use rustc_middle::mir::interpret::{
|
||||
AllocId, AllocInit, AllocRange, Allocation, ConstAllocation, Pointer, Scalar, alloc_range,
|
||||
};
|
||||
use rustc_middle::ty::{Ty, layout};
|
||||
|
||||
/// Creates new empty `Allocation` from given `Align`.
|
||||
fn new_empty_allocation(align: Align) -> Allocation {
|
||||
Allocation {
|
||||
bytes: Vec::new(),
|
||||
provenance: ProvenanceMap { ptrs: Vec::new() },
|
||||
align: align.bytes(),
|
||||
mutability: Mutability::Not,
|
||||
}
|
||||
use super::{SmirCtxt, Tables};
|
||||
use crate::rustc_smir::bridge::Allocation as _;
|
||||
use crate::rustc_smir::{Bridge, SmirError};
|
||||
|
||||
pub fn create_ty_and_layout<'tcx, B: Bridge>(
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<TyAndLayout<'tcx, Ty<'tcx>>, &'tcx layout::LayoutError<'tcx>> {
|
||||
use crate::rustc_smir::context::SmirTypingEnv;
|
||||
cx.tcx.layout_of(cx.fully_monomorphized().as_query_input(ty))
|
||||
}
|
||||
|
||||
// We need this method instead of a Stable implementation
|
||||
// because we need to get `Ty` of the const we are trying to create, to do that
|
||||
// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
|
||||
#[allow(rustc::usage_of_qualified_ty)]
|
||||
pub(crate) fn new_allocation<'tcx>(
|
||||
ty: rustc_middle::ty::Ty<'tcx>,
|
||||
const_value: ConstValue<'tcx>,
|
||||
tables: &mut Tables<'tcx>,
|
||||
) -> Allocation {
|
||||
try_new_allocation(ty, const_value, tables)
|
||||
.unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
|
||||
pub fn try_new_scalar<'tcx, B: Bridge>(
|
||||
layout: TyAndLayout<'tcx, Ty<'tcx>>,
|
||||
scalar: Scalar,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
) -> Result<Allocation, B::Error> {
|
||||
let size = scalar.size();
|
||||
let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ());
|
||||
allocation
|
||||
.write_scalar(&cx.tcx, alloc_range(Size::ZERO, size), scalar)
|
||||
.map_err(|e| B::Error::from_internal(e))?;
|
||||
|
||||
Ok(allocation)
|
||||
}
|
||||
|
||||
#[allow(rustc::usage_of_qualified_ty)]
|
||||
pub(crate) fn try_new_allocation<'tcx>(
|
||||
ty: rustc_middle::ty::Ty<'tcx>,
|
||||
const_value: ConstValue<'tcx>,
|
||||
tables: &mut Tables<'tcx>,
|
||||
) -> Result<Allocation, Error> {
|
||||
let layout = tables
|
||||
.tcx
|
||||
.layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
||||
.map_err(|e| e.stable(tables))?;
|
||||
Ok(match const_value {
|
||||
ConstValue::Scalar(scalar) => {
|
||||
let size = scalar.size();
|
||||
let mut allocation = rustc_middle::mir::interpret::Allocation::new(
|
||||
size,
|
||||
layout.align.abi,
|
||||
AllocInit::Uninit,
|
||||
(),
|
||||
);
|
||||
allocation
|
||||
.write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar)
|
||||
.map_err(|e| e.stable(tables))?;
|
||||
allocation.stable(tables)
|
||||
}
|
||||
ConstValue::ZeroSized => new_empty_allocation(layout.align.abi),
|
||||
ConstValue::Slice { data, meta } => {
|
||||
let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data);
|
||||
let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
|
||||
let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
|
||||
let scalar_meta =
|
||||
rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx);
|
||||
let mut allocation = rustc_middle::mir::interpret::Allocation::new(
|
||||
layout.size,
|
||||
layout.align.abi,
|
||||
AllocInit::Uninit,
|
||||
(),
|
||||
);
|
||||
allocation
|
||||
.write_scalar(
|
||||
&tables.tcx,
|
||||
alloc_range(Size::ZERO, tables.tcx.data_layout.pointer_size),
|
||||
scalar_ptr,
|
||||
)
|
||||
.map_err(|e| e.stable(tables))?;
|
||||
allocation
|
||||
.write_scalar(
|
||||
&tables.tcx,
|
||||
alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()),
|
||||
scalar_meta,
|
||||
)
|
||||
.map_err(|e| e.stable(tables))?;
|
||||
allocation.stable(tables)
|
||||
}
|
||||
ConstValue::Indirect { alloc_id, offset } => {
|
||||
let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory();
|
||||
allocation_filter(&alloc.0, alloc_range(offset, layout.size), tables)
|
||||
}
|
||||
})
|
||||
pub fn try_new_slice<'tcx, B: Bridge>(
|
||||
layout: TyAndLayout<'tcx, Ty<'tcx>>,
|
||||
data: ConstAllocation<'tcx>,
|
||||
meta: u64,
|
||||
cx: &SmirCtxt<'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);
|
||||
let scalar_ptr = Scalar::from_pointer(ptr, &cx.tcx);
|
||||
let scalar_meta: Scalar = Scalar::from_target_usize(meta, &cx.tcx);
|
||||
let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ());
|
||||
allocation
|
||||
.write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr)
|
||||
.map_err(|e| B::Error::from_internal(e))?;
|
||||
allocation
|
||||
.write_scalar(
|
||||
&cx.tcx,
|
||||
alloc_range(cx.tcx.data_layout.pointer_size, scalar_meta.size()),
|
||||
scalar_meta,
|
||||
)
|
||||
.map_err(|e| B::Error::from_internal(e))?;
|
||||
|
||||
Ok(allocation)
|
||||
}
|
||||
|
||||
pub fn try_new_indirect<'tcx, B: Bridge>(
|
||||
alloc_id: AllocId,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
) -> ConstAllocation<'tcx> {
|
||||
let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
|
||||
|
||||
alloc
|
||||
}
|
||||
|
||||
/// Creates an `Allocation` only from information within the `AllocRange`.
|
||||
pub(super) fn allocation_filter<'tcx>(
|
||||
pub fn allocation_filter<'tcx, B: Bridge>(
|
||||
alloc: &rustc_middle::mir::interpret::Allocation,
|
||||
alloc_range: AllocRange,
|
||||
tables: &mut Tables<'tcx>,
|
||||
) -> Allocation {
|
||||
tables: &mut Tables<'tcx, B>,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
) -> B::Allocation {
|
||||
let mut bytes: Vec<Option<u8>> = alloc
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(
|
||||
alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
|
||||
|
|
@ -117,15 +97,8 @@ pub(super) fn allocation_filter<'tcx>(
|
|||
.iter()
|
||||
.filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
|
||||
{
|
||||
ptrs.push((
|
||||
offset.bytes_usize() - alloc_range.start.bytes_usize(),
|
||||
tables.prov(prov.alloc_id()),
|
||||
));
|
||||
}
|
||||
Allocation {
|
||||
bytes,
|
||||
provenance: ProvenanceMap { ptrs },
|
||||
align: alloc.align.bytes(),
|
||||
mutability: alloc.mutability.stable(tables),
|
||||
ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), prov.alloc_id()));
|
||||
}
|
||||
|
||||
B::Allocation::new(bytes, ptrs, alloc.align.bytes(), alloc.mutability, tables, cx)
|
||||
}
|
||||
|
|
|
|||
59
compiler/rustc_smir/src/rustc_smir/bridge.rs
Normal file
59
compiler/rustc_smir/src/rustc_smir/bridge.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//! Defines a set of traits that is used for abstracting
|
||||
//! stable_mir's components that are needed in rustc_smir.
|
||||
//!
|
||||
//! These traits are really useful when programming
|
||||
//! in stable_mir-agnostic settings.
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::context::SmirCtxt;
|
||||
use super::{Bridge, Tables};
|
||||
|
||||
pub trait SmirError {
|
||||
fn new(msg: String) -> Self;
|
||||
fn from_internal<T: Debug>(err: T) -> Self;
|
||||
}
|
||||
|
||||
pub trait Prov<B: Bridge> {
|
||||
fn new(aid: B::AllocId) -> Self;
|
||||
}
|
||||
|
||||
pub trait Allocation<B: Bridge> {
|
||||
fn new<'tcx>(
|
||||
bytes: Vec<Option<u8>>,
|
||||
ptrs: Vec<(usize, rustc_middle::mir::interpret::AllocId)>,
|
||||
align: u64,
|
||||
mutability: rustc_middle::mir::Mutability,
|
||||
tables: &mut Tables<'tcx, B>,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! make_bridge_trait {
|
||||
($name:ident) => {
|
||||
pub trait $name<B: Bridge> {
|
||||
fn new(did: B::DefId) -> Self;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_bridge_trait!(CrateItem);
|
||||
make_bridge_trait!(AdtDef);
|
||||
make_bridge_trait!(ForeignModuleDef);
|
||||
make_bridge_trait!(ForeignDef);
|
||||
make_bridge_trait!(FnDef);
|
||||
make_bridge_trait!(ClosureDef);
|
||||
make_bridge_trait!(CoroutineDef);
|
||||
make_bridge_trait!(CoroutineClosureDef);
|
||||
make_bridge_trait!(AliasDef);
|
||||
make_bridge_trait!(ParamDef);
|
||||
make_bridge_trait!(BrNamedDef);
|
||||
make_bridge_trait!(TraitDef);
|
||||
make_bridge_trait!(GenericDef);
|
||||
make_bridge_trait!(ConstDef);
|
||||
make_bridge_trait!(ImplDef);
|
||||
make_bridge_trait!(RegionDef);
|
||||
make_bridge_trait!(CoroutineWitnessDef);
|
||||
make_bridge_trait!(AssocDef);
|
||||
make_bridge_trait!(OpaqueDef);
|
||||
make_bridge_trait!(StaticDef);
|
||||
|
|
@ -9,9 +9,6 @@ use rustc_middle::mir;
|
|||
use rustc_middle::mir::visit::MutVisitor;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::stable_mir;
|
||||
|
||||
/// Builds a monomorphic body for a given instance.
|
||||
pub(crate) struct BodyBuilder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
@ -31,8 +28,8 @@ impl<'tcx> BodyBuilder<'tcx> {
|
|||
/// Build a stable monomorphic body for a given instance based on the MIR body.
|
||||
///
|
||||
/// All constants are also evaluated.
|
||||
pub(crate) fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
|
||||
let body = tables.tcx.instance_mir(self.instance.def).clone();
|
||||
pub(crate) fn build(mut self) -> mir::Body<'tcx> {
|
||||
let body = self.tcx.instance_mir(self.instance.def).clone();
|
||||
let mono_body = if !self.instance.args.is_empty()
|
||||
// Without the `generic_const_exprs` feature gate, anon consts in signatures do not
|
||||
// get generic parameters. Which is wrong, but also not a problem without
|
||||
|
|
@ -40,7 +37,7 @@ impl<'tcx> BodyBuilder<'tcx> {
|
|||
|| self.tcx.def_kind(self.instance.def_id()) != DefKind::AnonConst
|
||||
{
|
||||
let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
tables.tcx,
|
||||
self.tcx,
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
ty::EarlyBinder::bind(body),
|
||||
);
|
||||
|
|
@ -50,7 +47,8 @@ impl<'tcx> BodyBuilder<'tcx> {
|
|||
// Already monomorphic.
|
||||
body
|
||||
};
|
||||
mono_body.stable(tables)
|
||||
|
||||
mono_body
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
762
compiler/rustc_smir/src/rustc_smir/context/impls.rs
Normal file
762
compiler/rustc_smir/src/rustc_smir/context/impls.rs
Normal file
|
|
@ -0,0 +1,762 @@
|
|||
//! Implementation of StableMIR Context.
|
||||
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
use std::iter;
|
||||
|
||||
use rustc_abi::{Endian, Layout, ReprOptions};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::{Attribute, LangItem};
|
||||
use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
|
||||
use rustc_middle::ty::util::Discr;
|
||||
use rustc_middle::ty::{
|
||||
AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder,
|
||||
ExistentialTraitRef, FnSig, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, List,
|
||||
PolyFnSig, ScalarInt, TraitDef, TraitRef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy,
|
||||
ValTree, VariantDef,
|
||||
};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_session::cstore::ForeignModule;
|
||||
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 crate::rustc_smir::builder::BodyBuilder;
|
||||
use crate::rustc_smir::{Bridge, SmirError, Tables, filter_def_ids};
|
||||
|
||||
impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'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> {
|
||||
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
|
||||
fn alloc_range(
|
||||
&self,
|
||||
offset: rustc_abi::Size,
|
||||
size: rustc_abi::Size,
|
||||
) -> mir::interpret::AllocRange {
|
||||
rustc_middle::mir::interpret::alloc_range(offset, size)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
|
||||
pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
|
||||
self.tcx.lift(value)
|
||||
}
|
||||
|
||||
pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> {
|
||||
self.tcx.adt_def(def_id)
|
||||
}
|
||||
|
||||
pub fn coroutine_movability(&self, def_id: DefId) -> ty::Movability {
|
||||
self.tcx.coroutine_movability(def_id)
|
||||
}
|
||||
|
||||
pub fn valtree_to_const_val(&self, key: ty::Value<'tcx>) -> ConstValue<'tcx> {
|
||||
self.tcx.valtree_to_const_val(key)
|
||||
}
|
||||
|
||||
/// Return whether the instance as a body available.
|
||||
///
|
||||
/// Items and intrinsics may have a body available from its definition.
|
||||
/// Shims body may be generated depending on their type.
|
||||
pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool {
|
||||
let def_id = instance.def_id();
|
||||
self.item_has_body(def_id)
|
||||
|| !matches!(
|
||||
instance.def,
|
||||
ty::InstanceKind::Virtual(..)
|
||||
| ty::InstanceKind::Intrinsic(..)
|
||||
| ty::InstanceKind::Item(..)
|
||||
)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
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
|
||||
} else {
|
||||
false
|
||||
};
|
||||
!must_override && self.tcx.is_mir_available(def_id)
|
||||
}
|
||||
|
||||
fn filter_fn_def(&self, def_id: DefId) -> Option<DefId> {
|
||||
if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
|
||||
Some(def_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_static_def(&self, def_id: DefId) -> Option<DefId> {
|
||||
matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id)
|
||||
}
|
||||
|
||||
pub fn target_endian(&self) -> Endian {
|
||||
self.tcx.data_layout.endian
|
||||
}
|
||||
|
||||
pub fn target_pointer_size(&self) -> usize {
|
||||
self.tcx.data_layout.pointer_size.bits().try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn entry_fn(&self) -> Option<DefId> {
|
||||
Some(self.tcx.entry_fn(())?.0)
|
||||
}
|
||||
|
||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||
pub fn all_local_items(&self) -> Vec<DefId> {
|
||||
self.tcx.mir_keys(()).iter().map(|item| item.to_def_id()).collect()
|
||||
}
|
||||
|
||||
/// Retrieve the body of a function.
|
||||
/// This function will panic if the body is not available.
|
||||
pub fn mir_body(&self, item: DefId) -> &'tcx Body<'tcx> {
|
||||
self.tcx.instance_mir(InstanceKind::Item(item))
|
||||
}
|
||||
|
||||
/// Check whether the body of a function is available.
|
||||
pub fn has_body(&self, def: DefId) -> bool {
|
||||
self.item_has_body(def)
|
||||
}
|
||||
|
||||
pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec<DefId> {
|
||||
self.tcx.foreign_modules(crate_num).keys().map(|mod_def_id| *mod_def_id).collect()
|
||||
}
|
||||
|
||||
/// Retrieve all functions defined in this crate.
|
||||
pub fn crate_functions(&self, crate_num: CrateNum) -> Vec<DefId> {
|
||||
filter_def_ids(self.tcx, crate_num, |def_id| self.filter_fn_def(def_id))
|
||||
}
|
||||
|
||||
/// Retrieve all static items defined in this crate.
|
||||
pub fn crate_statics(&self, crate_num: CrateNum) -> Vec<DefId> {
|
||||
filter_def_ids(self.tcx, crate_num, |def_id| self.filter_static_def(def_id))
|
||||
}
|
||||
|
||||
pub fn foreign_module(&self, mod_def: DefId) -> &ForeignModule {
|
||||
self.tcx.foreign_modules(mod_def.krate).get(&mod_def).unwrap()
|
||||
}
|
||||
|
||||
pub fn foreign_items(&self, mod_def: DefId) -> Vec<DefId> {
|
||||
self.tcx
|
||||
.foreign_modules(mod_def.krate)
|
||||
.get(&mod_def)
|
||||
.unwrap()
|
||||
.foreign_items
|
||||
.iter()
|
||||
.map(|item_def| *item_def)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn all_trait_decls(&self) -> impl Iterator<Item = DefId> {
|
||||
self.tcx.all_traits_including_private()
|
||||
}
|
||||
|
||||
pub fn trait_decls(&self, crate_num: CrateNum) -> Vec<DefId> {
|
||||
self.tcx.traits(crate_num).iter().map(|trait_def_id| *trait_def_id).collect()
|
||||
}
|
||||
|
||||
pub fn trait_decl(&self, trait_def: DefId) -> &'tcx TraitDef {
|
||||
self.tcx.trait_def(trait_def)
|
||||
}
|
||||
|
||||
pub fn all_trait_impls(&self) -> Vec<DefId> {
|
||||
iter::once(LOCAL_CRATE)
|
||||
.chain(self.tcx.crates(()).iter().copied())
|
||||
.flat_map(|cnum| self.tcx.trait_impls_in_crate(cnum).iter())
|
||||
.map(|impl_def_id| *impl_def_id)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn trait_impls(&self, crate_num: CrateNum) -> Vec<DefId> {
|
||||
self.tcx.trait_impls_in_crate(crate_num).iter().map(|impl_def_id| *impl_def_id).collect()
|
||||
}
|
||||
|
||||
pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder<'tcx, TraitRef<'tcx>> {
|
||||
self.tcx.impl_trait_ref(impl_def).unwrap()
|
||||
}
|
||||
|
||||
pub fn generics_of(&self, def_id: DefId) -> &'tcx ty::Generics {
|
||||
self.tcx.generics_of(def_id)
|
||||
}
|
||||
|
||||
pub fn predicates_of(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
) -> (Option<DefId>, Vec<(ty::PredicateKind<'tcx>, Span)>) {
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
|
||||
(
|
||||
parent,
|
||||
predicates
|
||||
.iter()
|
||||
.map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn explicit_predicates_of(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
) -> (Option<DefId>, Vec<(ty::PredicateKind<'tcx>, Span)>) {
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
|
||||
(
|
||||
parent,
|
||||
predicates
|
||||
.iter()
|
||||
.map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn crate_name(&self, crate_num: CrateNum) -> String {
|
||||
self.tcx.crate_name(crate_num).to_string()
|
||||
}
|
||||
|
||||
pub fn crate_is_local(&self, crate_num: CrateNum) -> bool {
|
||||
crate_num == LOCAL_CRATE
|
||||
}
|
||||
|
||||
pub fn crate_num_id(&self, crate_num: CrateNum) -> usize {
|
||||
crate_num.into()
|
||||
}
|
||||
|
||||
pub fn local_crate_num(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
|
||||
/// Retrieve a list of all external crates.
|
||||
pub fn external_crates(&self) -> Vec<CrateNum> {
|
||||
self.tcx.crates(()).iter().map(|crate_num| *crate_num).collect()
|
||||
}
|
||||
|
||||
/// Find a crate with the given name.
|
||||
pub fn find_crates(&self, name: &str) -> Vec<CrateNum> {
|
||||
let crates: Vec<CrateNum> = [LOCAL_CRATE]
|
||||
.iter()
|
||||
.chain(self.tcx.crates(()).iter())
|
||||
.filter_map(|crate_num| {
|
||||
let crate_name = self.tcx.crate_name(*crate_num).to_string();
|
||||
(name == crate_name).then(|| *crate_num)
|
||||
})
|
||||
.collect();
|
||||
crates
|
||||
}
|
||||
|
||||
/// Returns the name of given `DefId`.
|
||||
pub fn def_name(&self, def_id: DefId, trimmed: bool) -> String {
|
||||
if trimmed {
|
||||
with_forced_trimmed_paths!(self.tcx.def_path_str(def_id))
|
||||
} else {
|
||||
with_no_trimmed_paths!(self.tcx.def_path_str(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Return registered tool attributes with the given attribute name.
|
||||
///
|
||||
/// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool
|
||||
/// attributes will simply return an empty list.
|
||||
///
|
||||
/// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`.
|
||||
/// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
|
||||
pub fn tool_attrs(&self, def_id: DefId, attr: &[String]) -> Vec<(String, Span)> {
|
||||
let attr_name: Vec<_> = attr.iter().map(|seg| Symbol::intern(&seg)).collect();
|
||||
self.tcx
|
||||
.get_attrs_by_path(def_id, &attr_name)
|
||||
.filter_map(|attribute| {
|
||||
if let Attribute::Unparsed(u) = attribute {
|
||||
let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute);
|
||||
Some((attr_str, u.span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get all tool attributes of a definition.
|
||||
pub fn all_tool_attrs(&self, did: DefId) -> Vec<(String, Span)> {
|
||||
let attrs_iter = if let Some(did) = did.as_local() {
|
||||
self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(did)).iter()
|
||||
} else {
|
||||
self.tcx.attrs_for_def(did).iter()
|
||||
};
|
||||
attrs_iter
|
||||
.filter_map(|attribute| {
|
||||
if let Attribute::Unparsed(u) = attribute {
|
||||
let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute);
|
||||
Some((attr_str, u.span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns printable, human readable form of `Span`.
|
||||
pub fn span_to_string(&self, span: Span) -> String {
|
||||
self.tcx.sess.source_map().span_to_diagnostic_string(span)
|
||||
}
|
||||
|
||||
/// Return filename from given `Span`, for diagnostic purposes.
|
||||
pub fn get_filename(&self, span: Span) -> String {
|
||||
self.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_filename(span)
|
||||
.display(FileNameDisplayPreference::Local)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Return lines corresponding to this `Span`.
|
||||
pub fn get_lines(&self, span: Span) -> (usize, usize, usize, usize) {
|
||||
let lines = &self.tcx.sess.source_map().span_to_location_info(span);
|
||||
(lines.1, lines.2, lines.3, lines.4)
|
||||
}
|
||||
|
||||
/// Returns the `kind` of given `DefId`.
|
||||
pub fn def_kind(&self, item: DefId) -> DefKind {
|
||||
self.tcx.def_kind(item)
|
||||
}
|
||||
|
||||
/// Returns whether this is a foreign item.
|
||||
pub fn is_foreign_item(&self, item: DefId) -> bool {
|
||||
self.tcx.is_foreign_item(item)
|
||||
}
|
||||
|
||||
/// Returns the kind of a given foreign item.
|
||||
pub fn foreign_item_kind(&self, def_id: DefId) -> DefKind {
|
||||
self.tcx.def_kind(def_id)
|
||||
}
|
||||
|
||||
/// Returns the kind of a given algebraic data type.
|
||||
pub fn adt_kind(&self, def: AdtDef<'tcx>) -> AdtKind {
|
||||
def.adt_kind()
|
||||
}
|
||||
|
||||
/// Returns if the ADT is a box.
|
||||
pub fn adt_is_box(&self, def: AdtDef<'tcx>) -> bool {
|
||||
def.is_box()
|
||||
}
|
||||
|
||||
/// Returns whether this ADT is simd.
|
||||
pub fn adt_is_simd(&self, def: AdtDef<'tcx>) -> bool {
|
||||
def.repr().simd()
|
||||
}
|
||||
|
||||
/// Returns whether this definition is a C string.
|
||||
pub fn adt_is_cstr(&self, def_id: DefId) -> bool {
|
||||
self.tcx.is_lang_item(def_id, LangItem::CStr)
|
||||
}
|
||||
|
||||
/// Returns the representation options for this ADT.
|
||||
pub fn adt_repr(&self, def: AdtDef<'tcx>) -> ReprOptions {
|
||||
def.repr()
|
||||
}
|
||||
|
||||
/// Retrieve the function signature for the given generic arguments.
|
||||
pub fn fn_sig(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
) -> Binder<'tcx, FnSig<'tcx>> {
|
||||
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref);
|
||||
sig
|
||||
}
|
||||
|
||||
/// Retrieve the intrinsic definition if the item corresponds one.
|
||||
pub fn intrinsic(&self, def_id: DefId) -> Option<IntrinsicDef> {
|
||||
let intrinsic = self.tcx.intrinsic_raw(def_id);
|
||||
intrinsic
|
||||
}
|
||||
|
||||
/// Retrieve the plain function name of an intrinsic.
|
||||
pub fn intrinsic_name(&self, def_id: DefId) -> String {
|
||||
self.tcx.intrinsic(def_id).unwrap().name.to_string()
|
||||
}
|
||||
|
||||
/// Retrieve the closure signature for the given generic arguments.
|
||||
pub fn closure_sig(&self, args_ref: GenericArgsRef<'tcx>) -> Binder<'tcx, FnSig<'tcx>> {
|
||||
args_ref.as_closure().sig()
|
||||
}
|
||||
|
||||
/// The number of variants in this ADT.
|
||||
pub fn adt_variants_len(&self, def: AdtDef<'tcx>) -> usize {
|
||||
def.variants().len()
|
||||
}
|
||||
|
||||
/// Discriminant for a given variant index of AdtDef.
|
||||
pub fn adt_discr_for_variant(
|
||||
&self,
|
||||
adt: AdtDef<'tcx>,
|
||||
variant: rustc_abi::VariantIdx,
|
||||
) -> Discr<'tcx> {
|
||||
adt.discriminant_for_variant(self.tcx, variant)
|
||||
}
|
||||
|
||||
/// Discriminant for a given variand index and args of a coroutine.
|
||||
pub fn coroutine_discr_for_variant(
|
||||
&self,
|
||||
coroutine: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
variant: rustc_abi::VariantIdx,
|
||||
) -> Discr<'tcx> {
|
||||
args.as_coroutine().discriminant_for_variant(coroutine, self.tcx, variant)
|
||||
}
|
||||
|
||||
/// The name of a variant.
|
||||
pub fn variant_name(&self, def: &'tcx VariantDef) -> String {
|
||||
def.name.to_string()
|
||||
}
|
||||
|
||||
/// Evaluate constant as a target usize.
|
||||
pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
|
||||
use crate::rustc_smir::context::SmirTypingEnv;
|
||||
cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())
|
||||
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
|
||||
pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result<u64, B::Error> {
|
||||
cnst.try_to_target_usize(self.tcx)
|
||||
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
|
||||
pub(crate) fn try_new_const_zst(
|
||||
&self,
|
||||
ty_internal: Ty<'tcx>,
|
||||
) -> Result<MirConst<'tcx>, B::Error> {
|
||||
let size = self
|
||||
.tcx
|
||||
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
|
||||
.map_err(|err| {
|
||||
B::Error::new(format!(
|
||||
"Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
|
||||
))
|
||||
})?
|
||||
.size;
|
||||
if size.bytes() != 0 {
|
||||
return Err(B::Error::new(format!(
|
||||
"Cannot create a zero-sized constant for type `{ty_internal}`: \
|
||||
Type `{ty_internal}` has {} bytes",
|
||||
size.bytes()
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal)))
|
||||
}
|
||||
|
||||
pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> {
|
||||
ty::Const::zero_sized(self.tcx, ty_internal)
|
||||
}
|
||||
|
||||
/// Create a new constant that represents the given string value.
|
||||
pub fn new_const_str(&self, value: &str) -> MirConst<'tcx> {
|
||||
let ty = Ty::new_static_str(self.tcx);
|
||||
let bytes = value.as_bytes();
|
||||
let valtree = ValTree::from_raw_bytes(self.tcx, bytes);
|
||||
let cv = ty::Value { ty, valtree };
|
||||
let val = self.tcx.valtree_to_const_val(cv);
|
||||
MirConst::from_value(val, ty)
|
||||
}
|
||||
|
||||
/// Create a new constant that represents the given boolean value.
|
||||
pub fn new_const_bool(&self, value: bool) -> MirConst<'tcx> {
|
||||
MirConst::from_bool(self.tcx, value)
|
||||
}
|
||||
|
||||
pub fn try_new_const_uint(
|
||||
&self,
|
||||
value: u128,
|
||||
ty_internal: Ty<'tcx>,
|
||||
) -> Result<MirConst<'tcx>, B::Error> {
|
||||
let size = self
|
||||
.tcx
|
||||
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
|
||||
.unwrap()
|
||||
.size;
|
||||
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
|
||||
B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
|
||||
})?;
|
||||
Ok(self.mir_const_from_scalar(Scalar::Int(scalar), ty_internal))
|
||||
}
|
||||
|
||||
pub fn try_new_ty_const_uint(
|
||||
&self,
|
||||
value: u128,
|
||||
ty_internal: Ty<'tcx>,
|
||||
) -> Result<ty::Const<'tcx>, B::Error> {
|
||||
let size = self
|
||||
.tcx
|
||||
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
|
||||
.unwrap()
|
||||
.size;
|
||||
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
|
||||
B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
|
||||
})?;
|
||||
|
||||
Ok(self.ty_const_new_value(ValTree::from_scalar_int(self.tcx, scalar), ty_internal))
|
||||
}
|
||||
|
||||
pub fn ty_new_uint(&self, ty: UintTy) -> Ty<'tcx> {
|
||||
Ty::new_uint(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn mir_const_from_scalar(&self, s: Scalar, ty: Ty<'tcx>) -> MirConst<'tcx> {
|
||||
MirConst::from_scalar(self.tcx, s, ty)
|
||||
}
|
||||
|
||||
pub fn ty_const_new_value(&self, valtree: ValTree<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
|
||||
ty::Const::new_value(self.tcx, valtree, ty)
|
||||
}
|
||||
|
||||
pub fn ty_valtree_from_scalar_int(&self, i: ScalarInt) -> ValTree<'tcx> {
|
||||
ValTree::from_scalar_int(self.tcx, i)
|
||||
}
|
||||
|
||||
/// Create a new type from the given kind.
|
||||
pub fn new_rigid_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
|
||||
self.tcx.mk_ty_from_kind(internal_kind)
|
||||
}
|
||||
|
||||
/// Create a new box type, `Box<T>`, for the given inner type `T`.
|
||||
pub fn new_box_ty(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
ty::Ty::new_box(self.tcx, ty)
|
||||
}
|
||||
|
||||
/// Returns the type of given crate item.
|
||||
pub fn def_ty(&self, item: DefId) -> Ty<'tcx> {
|
||||
self.tcx.type_of(item).instantiate_identity()
|
||||
}
|
||||
|
||||
/// Returns the type of given definition instantiated with the given arguments.
|
||||
pub fn def_ty_with_args(&self, item: DefId, args_ref: GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
||||
let def_ty = self.tcx.type_of(item);
|
||||
self.tcx.instantiate_and_normalize_erasing_regions(
|
||||
args_ref,
|
||||
self.fully_monomorphized(),
|
||||
def_ty,
|
||||
)
|
||||
}
|
||||
|
||||
/// `Span` of an item.
|
||||
pub fn span_of_an_item(&self, def_id: DefId) -> Span {
|
||||
self.tcx.def_span(def_id)
|
||||
}
|
||||
|
||||
pub fn ty_const_pretty(&self, ct: ty::Const<'tcx>) -> String {
|
||||
ct.to_string()
|
||||
}
|
||||
|
||||
/// Obtain the representation of a type.
|
||||
pub fn ty_pretty(&self, ty: Ty<'tcx>) -> String {
|
||||
ty.to_string()
|
||||
}
|
||||
|
||||
/// Obtain the kind of a type.
|
||||
pub fn ty_kind(&self, ty: Ty<'tcx>) -> &'tcx TyKind<'tcx> {
|
||||
ty.kind()
|
||||
}
|
||||
|
||||
/// Get the discriminant Ty for this Ty if there's one.
|
||||
pub fn rigid_ty_discriminant_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
|
||||
let internal_ty = self.tcx.mk_ty_from_kind(internal_kind);
|
||||
internal_ty.discriminant_ty(self.tcx)
|
||||
}
|
||||
|
||||
/// Get the body of an Instance which is already monomorphized.
|
||||
pub fn instance_body(&self, instance: ty::Instance<'tcx>) -> Option<Body<'tcx>> {
|
||||
self.instance_has_body(instance).then(|| BodyBuilder::new(self.tcx, instance).build())
|
||||
}
|
||||
|
||||
/// Get the instance type with generic instantiations applied and lifetimes erased.
|
||||
pub fn instance_ty(&self, instance: ty::Instance<'tcx>) -> Ty<'tcx> {
|
||||
assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
|
||||
instance.ty(self.tcx, self.fully_monomorphized())
|
||||
}
|
||||
|
||||
/// Get the instantiation types.
|
||||
pub fn instance_args(&self, instance: ty::Instance<'tcx>) -> GenericArgsRef<'tcx> {
|
||||
instance.args
|
||||
}
|
||||
|
||||
/// Get an instance ABI.
|
||||
pub fn instance_abi(
|
||||
&self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
|
||||
Ok(self.fn_abi_of_instance(instance, List::empty())?)
|
||||
}
|
||||
|
||||
/// Get the ABI of a function pointer.
|
||||
pub fn fn_ptr_abi(&self, sig: PolyFnSig<'tcx>) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
|
||||
Ok(self.fn_abi_of_fn_ptr(sig, List::empty())?)
|
||||
}
|
||||
|
||||
/// Get the instance.
|
||||
pub fn instance_def_id(
|
||||
&self,
|
||||
instances: ty::Instance<'tcx>,
|
||||
tables: &mut Tables<'_, B>,
|
||||
) -> B::DefId {
|
||||
let def_id = instances.def_id();
|
||||
tables.create_def_id(def_id)
|
||||
}
|
||||
|
||||
/// Get the instance mangled name.
|
||||
pub fn instance_mangled_name(&self, instance: ty::Instance<'tcx>) -> String {
|
||||
self.tcx.symbol_name(instance).name.to_string()
|
||||
}
|
||||
|
||||
/// Check if this is an empty DropGlue shim.
|
||||
pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool {
|
||||
matches!(instance.def, ty::InstanceKind::DropGlue(_, None))
|
||||
}
|
||||
|
||||
/// Convert a non-generic crate item into an instance.
|
||||
/// This function will panic if the item is generic.
|
||||
pub fn mono_instance(&self, def_id: DefId) -> Instance<'tcx> {
|
||||
Instance::mono(self.tcx, def_id)
|
||||
}
|
||||
|
||||
/// Item requires monomorphization.
|
||||
pub fn requires_monomorphization(&self, def_id: DefId) -> bool {
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let result = generics.requires_monomorphization(self.tcx);
|
||||
result
|
||||
}
|
||||
|
||||
/// Resolve an instance from the given function definition and generic arguments.
|
||||
pub fn resolve_instance(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
match Instance::try_resolve(self.tcx, self.fully_monomorphized(), def_id, args_ref) {
|
||||
Ok(Some(instance)) => Some(instance),
|
||||
Ok(None) | Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve an instance for drop_in_place for the given type.
|
||||
pub fn resolve_drop_in_place(&self, internal_ty: Ty<'tcx>) -> Instance<'tcx> {
|
||||
let instance = Instance::resolve_drop_in_place(self.tcx, internal_ty);
|
||||
instance
|
||||
}
|
||||
|
||||
/// Resolve instance for a function pointer.
|
||||
pub fn resolve_for_fn_ptr(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
Instance::resolve_for_fn_ptr(self.tcx, self.fully_monomorphized(), def_id, args_ref)
|
||||
}
|
||||
|
||||
/// Resolve instance for a closure with the requested type.
|
||||
pub fn resolve_closure(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
closure_kind: ClosureKind,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
Some(Instance::resolve_closure(self.tcx, def_id, args_ref, closure_kind))
|
||||
}
|
||||
|
||||
/// Try to evaluate an instance into a constant.
|
||||
pub fn eval_instance(
|
||||
&self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
self.tcx.const_eval_instance(
|
||||
self.fully_monomorphized(),
|
||||
instance,
|
||||
self.tcx.def_span(instance.def_id()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Evaluate a static's initializer.
|
||||
pub fn eval_static_initializer(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
) -> Result<ConstAllocation<'tcx>, ErrorHandled> {
|
||||
self.tcx.eval_static_initializer(def_id)
|
||||
}
|
||||
|
||||
/// Retrieve global allocation for the given allocation ID.
|
||||
pub fn global_alloc(&self, alloc_id: AllocId) -> GlobalAlloc<'tcx> {
|
||||
self.tcx.global_alloc(alloc_id)
|
||||
}
|
||||
|
||||
/// Retrieve the id for the virtual table.
|
||||
pub fn vtable_allocation(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
|
||||
) -> AllocId {
|
||||
let alloc_id = self.tcx.vtable_allocation((
|
||||
ty,
|
||||
trait_ref.map(|principal| self.tcx.instantiate_bound_regions_with_erased(principal)),
|
||||
));
|
||||
alloc_id
|
||||
}
|
||||
|
||||
/// Retrieve the instance name for diagnostic messages.
|
||||
///
|
||||
/// This will return the specialized name, e.g., `Vec<char>::new`.
|
||||
pub fn instance_name(&self, instance: ty::Instance<'tcx>, trimmed: bool) -> String {
|
||||
if trimmed {
|
||||
with_forced_trimmed_paths!(
|
||||
self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
|
||||
)
|
||||
} else {
|
||||
with_no_trimmed_paths!(
|
||||
self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the layout of a type.
|
||||
pub fn ty_layout(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, B::Error> {
|
||||
let layout = self.layout_of(ty)?.layout;
|
||||
Ok(layout)
|
||||
}
|
||||
|
||||
/// Get the resulting type of binary operation.
|
||||
pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty<'tcx>, lhs: Ty<'tcx>) -> Ty<'tcx> {
|
||||
bin_op.ty(self.tcx, rhs, lhs)
|
||||
}
|
||||
|
||||
/// Get the resulting type of unary operation.
|
||||
pub fn unop_ty(&self, un_op: UnOp, arg: Ty<'tcx>) -> Ty<'tcx> {
|
||||
un_op.ty(self.tcx, arg)
|
||||
}
|
||||
|
||||
/// Get all associated items of a definition.
|
||||
pub fn associated_items(&self, def_id: DefId) -> Vec<AssocItem> {
|
||||
let assoc_items = if self.tcx.is_trait_alias(def_id) {
|
||||
Vec::new()
|
||||
} else {
|
||||
self.tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
.iter()
|
||||
.map(|did| self.tcx.associated_item(*did))
|
||||
.collect()
|
||||
};
|
||||
assoc_items
|
||||
}
|
||||
}
|
||||
79
compiler/rustc_smir/src/rustc_smir/context/mod.rs
Normal file
79
compiler/rustc_smir/src/rustc_smir/context/mod.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//! Implementation of StableMIR Context.
|
||||
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use rustc_abi::HasDataLayout;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOfHelpers};
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
|
||||
use crate::rustc_smir::{Bridge, SmirError};
|
||||
|
||||
mod impls;
|
||||
mod traits;
|
||||
|
||||
pub use traits::*;
|
||||
|
||||
/// Provides direct access to rustc's internal queries.
|
||||
///
|
||||
/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through
|
||||
/// this context to obtain rustc-level information.
|
||||
pub struct SmirCtxt<'tcx, B: Bridge> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
_marker: PhantomData<B>,
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirCtxt<'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> {
|
||||
type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, B::Error>;
|
||||
|
||||
#[inline]
|
||||
fn handle_fn_abi_err(
|
||||
&self,
|
||||
err: ty::layout::FnAbiError<'tcx>,
|
||||
_span: rustc_span::Span,
|
||||
fn_abi_request: ty::layout::FnAbiRequest<'tcx>,
|
||||
) -> B::Error {
|
||||
B::Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
|
||||
type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, B::Error>;
|
||||
|
||||
#[inline]
|
||||
fn handle_layout_err(
|
||||
&self,
|
||||
err: ty::layout::LayoutError<'tcx>,
|
||||
_span: rustc_span::Span,
|
||||
ty: Ty<'tcx>,
|
||||
) -> B::Error {
|
||||
B::Error::new(format!("Failed to get layout for `{ty}`: {err}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for SmirCtxt<'tcx, B> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasDataLayout for SmirCtxt<'tcx, B> {
|
||||
fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
|
||||
self.tcx.data_layout()
|
||||
}
|
||||
}
|
||||
46
compiler/rustc_smir/src/rustc_smir/context/traits.rs
Normal file
46
compiler/rustc_smir/src/rustc_smir/context/traits.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//! 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
|
||||
//! interface regardless of internal compiler changes.
|
||||
|
||||
use rustc_middle::mir::interpret::AllocRange;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::def_id::DefId;
|
||||
|
||||
pub trait SmirExistentialProjection<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
term: ty::Term<'tcx>,
|
||||
) -> ty::ExistentialProjection<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirExistentialTraitRef<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> ty::ExistentialTraitRef<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirTraitRef<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> ty::TraitRef<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirTy<'tcx> {
|
||||
fn new_foreign(&self, def_id: DefId) -> Ty<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirTypingEnv<'tcx> {
|
||||
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirAllocRange<'tcx> {
|
||||
fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange;
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
//! Handle the conversion of different internal errors into a stable version.
|
||||
//!
|
||||
//! Currently we encode everything as [stable_mir::Error], which is represented as a string.
|
||||
|
||||
use rustc_middle::mir::interpret::AllocError;
|
||||
use rustc_middle::ty::layout::LayoutError;
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::stable_mir;
|
||||
|
||||
impl<'tcx> Stable<'tcx> for LayoutError<'tcx> {
|
||||
type T = stable_mir::Error;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
stable_mir::Error::new(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for AllocError {
|
||||
type T = stable_mir::Error;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
stable_mir::Error::new(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
|
@ -7,91 +7,263 @@
|
|||
//!
|
||||
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
|
||||
|
||||
use std::marker::PointeeSized;
|
||||
use std::ops::RangeInclusive;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Index;
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use bridge::*;
|
||||
use context::SmirCtxt;
|
||||
use rustc_data_structures::fx::{self, FxIndexMap};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::AllocId;
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use stable_mir::abi::Layout;
|
||||
use stable_mir::mir::mono::{InstanceDef, StaticDef};
|
||||
use stable_mir::ty::{FnDef, MirConstId, Span, TyConstId};
|
||||
use stable_mir::{CtorKind, ItemKind};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::rustc_internal::IndexMap;
|
||||
use crate::stable_mir;
|
||||
|
||||
mod alloc;
|
||||
pub mod alloc;
|
||||
pub mod bridge;
|
||||
mod builder;
|
||||
pub mod context;
|
||||
mod convert;
|
||||
|
||||
pub struct Tables<'tcx> {
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
|
||||
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
|
||||
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
|
||||
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
|
||||
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||
pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, TyConstId>,
|
||||
pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, MirConstId>,
|
||||
pub(crate) layouts: IndexMap<rustc_abi::Layout<'tcx>, Layout>,
|
||||
/// A container which is used for TLS.
|
||||
pub struct SmirContainer<'tcx, B: Bridge> {
|
||||
pub tables: RefCell<Tables<'tcx, B>>,
|
||||
pub cx: RefCell<SmirCtxt<'tcx, B>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Tables<'tcx> {
|
||||
pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
|
||||
pub struct Tables<'tcx, B: Bridge> {
|
||||
pub def_ids: IndexMap<DefId, B::DefId>,
|
||||
pub alloc_ids: IndexMap<AllocId, B::AllocId>,
|
||||
pub spans: IndexMap<rustc_span::Span, B::Span>,
|
||||
pub types: IndexMap<Ty<'tcx>, B::Ty>,
|
||||
pub instances: IndexMap<ty::Instance<'tcx>, B::InstanceDef>,
|
||||
pub ty_consts: IndexMap<ty::Const<'tcx>, B::TyConstId>,
|
||||
pub mir_consts: IndexMap<mir::Const<'tcx>, B::MirConstId>,
|
||||
pub layouts: IndexMap<rustc_abi::Layout<'tcx>, B::Layout>,
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> Default for Tables<'tcx, B> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
def_ids: IndexMap::default(),
|
||||
alloc_ids: IndexMap::default(),
|
||||
spans: IndexMap::default(),
|
||||
types: IndexMap::default(),
|
||||
instances: IndexMap::default(),
|
||||
ty_consts: IndexMap::default(),
|
||||
mir_consts: IndexMap::default(),
|
||||
layouts: IndexMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> Index<B::DefId> for Tables<'tcx, B> {
|
||||
type Output = DefId;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, index: B::DefId) -> &Self::Output {
|
||||
&self.def_ids[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> Tables<'tcx, B> {
|
||||
pub fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty {
|
||||
self.types.create_or_fetch(ty)
|
||||
}
|
||||
|
||||
pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId {
|
||||
pub fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId {
|
||||
self.ty_consts.create_or_fetch(ct)
|
||||
}
|
||||
|
||||
pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId {
|
||||
pub fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId {
|
||||
self.mir_consts.create_or_fetch(constant)
|
||||
}
|
||||
|
||||
/// Return whether the instance as a body available.
|
||||
///
|
||||
/// Items and intrinsics may have a body available from its definition.
|
||||
/// Shims body may be generated depending on their type.
|
||||
pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool {
|
||||
let def_id = instance.def_id();
|
||||
self.item_has_body(def_id)
|
||||
|| !matches!(
|
||||
instance.def,
|
||||
ty::InstanceKind::Virtual(..)
|
||||
| ty::InstanceKind::Intrinsic(..)
|
||||
| ty::InstanceKind::Item(..)
|
||||
)
|
||||
pub fn create_def_id(&mut self, did: DefId) -> B::DefId {
|
||||
self.def_ids.create_or_fetch(did)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
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
|
||||
} else {
|
||||
false
|
||||
};
|
||||
!must_override && self.tcx.is_mir_available(def_id)
|
||||
pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId {
|
||||
self.alloc_ids.create_or_fetch(aid)
|
||||
}
|
||||
|
||||
fn to_fn_def(&mut self, def_id: DefId) -> Option<FnDef> {
|
||||
if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
|
||||
Some(self.fn_def(def_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
pub fn create_span(&mut self, span: Span) -> B::Span {
|
||||
self.spans.create_or_fetch(span)
|
||||
}
|
||||
|
||||
fn to_static(&mut self, def_id: DefId) -> Option<StaticDef> {
|
||||
matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| self.static_def(def_id))
|
||||
pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef {
|
||||
self.instances.create_or_fetch(instance)
|
||||
}
|
||||
|
||||
pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout {
|
||||
self.layouts.create_or_fetch(layout)
|
||||
}
|
||||
|
||||
pub fn crate_item(&mut self, did: rustc_span::def_id::DefId) -> B::CrateItem {
|
||||
B::CrateItem::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn adt_def(&mut self, did: rustc_span::def_id::DefId) -> B::AdtDef {
|
||||
B::AdtDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn foreign_module_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignModuleDef {
|
||||
B::ForeignModuleDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn foreign_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignDef {
|
||||
B::ForeignDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn fn_def(&mut self, did: rustc_span::def_id::DefId) -> B::FnDef {
|
||||
B::FnDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn closure_def(&mut self, did: rustc_span::def_id::DefId) -> B::ClosureDef {
|
||||
B::ClosureDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_def(&mut self, did: rustc_span::def_id::DefId) -> B::CoroutineDef {
|
||||
B::CoroutineDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_closure_def(
|
||||
&mut self,
|
||||
did: rustc_span::def_id::DefId,
|
||||
) -> B::CoroutineClosureDef {
|
||||
B::CoroutineClosureDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn alias_def(&mut self, did: rustc_span::def_id::DefId) -> B::AliasDef {
|
||||
B::AliasDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn param_def(&mut self, did: rustc_span::def_id::DefId) -> B::ParamDef {
|
||||
B::ParamDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn br_named_def(&mut self, did: rustc_span::def_id::DefId) -> B::BrNamedDef {
|
||||
B::BrNamedDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn trait_def(&mut self, did: rustc_span::def_id::DefId) -> B::TraitDef {
|
||||
B::TraitDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn generic_def(&mut self, did: rustc_span::def_id::DefId) -> B::GenericDef {
|
||||
B::GenericDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn const_def(&mut self, did: rustc_span::def_id::DefId) -> B::ConstDef {
|
||||
B::ConstDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn impl_def(&mut self, did: rustc_span::def_id::DefId) -> B::ImplDef {
|
||||
B::ImplDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn region_def(&mut self, did: rustc_span::def_id::DefId) -> B::RegionDef {
|
||||
B::RegionDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn coroutine_witness_def(
|
||||
&mut self,
|
||||
did: rustc_span::def_id::DefId,
|
||||
) -> B::CoroutineWitnessDef {
|
||||
B::CoroutineWitnessDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> B::AssocDef {
|
||||
B::AssocDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn opaque_def(&mut self, did: rustc_span::def_id::DefId) -> B::OpaqueDef {
|
||||
B::OpaqueDef::new(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn prov(&mut self, aid: rustc_middle::mir::interpret::AllocId) -> B::Prov {
|
||||
B::Prov::new(self.create_alloc_id(aid))
|
||||
}
|
||||
|
||||
pub fn static_def(&mut self, did: rustc_span::def_id::DefId) -> B::StaticDef {
|
||||
B::StaticDef::new(self.create_def_id(did))
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait defining types that are used to emulate StableMIR components, which is really
|
||||
/// useful when programming in stable_mir-agnostic settings.
|
||||
pub trait Bridge: Sized {
|
||||
type DefId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type AllocId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type Span: Copy + Debug + PartialEq + IndexedVal;
|
||||
type Ty: Copy + Debug + PartialEq + IndexedVal;
|
||||
type InstanceDef: Copy + Debug + PartialEq + IndexedVal;
|
||||
type TyConstId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type MirConstId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type Layout: Copy + Debug + PartialEq + IndexedVal;
|
||||
|
||||
type Error: SmirError;
|
||||
type CrateItem: CrateItem<Self>;
|
||||
type AdtDef: AdtDef<Self>;
|
||||
type ForeignModuleDef: ForeignModuleDef<Self>;
|
||||
type ForeignDef: ForeignDef<Self>;
|
||||
type FnDef: FnDef<Self>;
|
||||
type ClosureDef: ClosureDef<Self>;
|
||||
type CoroutineDef: CoroutineDef<Self>;
|
||||
type CoroutineClosureDef: CoroutineClosureDef<Self>;
|
||||
type AliasDef: AliasDef<Self>;
|
||||
type ParamDef: ParamDef<Self>;
|
||||
type BrNamedDef: BrNamedDef<Self>;
|
||||
type TraitDef: TraitDef<Self>;
|
||||
type GenericDef: GenericDef<Self>;
|
||||
type ConstDef: ConstDef<Self>;
|
||||
type ImplDef: ImplDef<Self>;
|
||||
type RegionDef: RegionDef<Self>;
|
||||
type CoroutineWitnessDef: CoroutineWitnessDef<Self>;
|
||||
type AssocDef: AssocDef<Self>;
|
||||
type OpaqueDef: OpaqueDef<Self>;
|
||||
type Prov: Prov<Self>;
|
||||
type StaticDef: StaticDef<Self>;
|
||||
|
||||
type Allocation: Allocation<Self>;
|
||||
}
|
||||
|
||||
pub trait IndexedVal {
|
||||
fn to_val(index: usize) -> Self;
|
||||
|
||||
fn to_index(&self) -> usize;
|
||||
}
|
||||
|
||||
/// Similar to rustc's `FxIndexMap`, `IndexMap` with extra
|
||||
/// safety features added.
|
||||
pub struct IndexMap<K, V> {
|
||||
index_map: fx::FxIndexMap<K, V>,
|
||||
}
|
||||
|
||||
impl<K, V> Default for IndexMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self { index_map: FxIndexMap::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> {
|
||||
pub fn create_or_fetch(&mut self, key: K) -> V {
|
||||
let len = self.index_map.len();
|
||||
let v = self.index_map.entry(key).or_insert(V::to_val(len));
|
||||
*v
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V>
|
||||
for IndexMap<K, V>
|
||||
{
|
||||
type Output = K;
|
||||
|
||||
fn index(&self, index: V) -> &Self::Output {
|
||||
let (k, v) = self.index_map.get_index(index.to_index()).unwrap();
|
||||
assert_eq!(*v, index, "Provided value doesn't match with indexed value");
|
||||
k
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,124 +284,3 @@ where
|
|||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a stable mir crate from a given crate number.
|
||||
pub(crate) fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
|
||||
let crate_name = tcx.crate_name(crate_num).to_string();
|
||||
let is_local = crate_num == LOCAL_CRATE;
|
||||
debug!(?crate_name, ?crate_num, "smir_crate");
|
||||
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
|
||||
}
|
||||
|
||||
pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
|
||||
match kind {
|
||||
DefKind::Mod
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::TyParam
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Macro(_)
|
||||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::GlobalAsm => {
|
||||
unreachable!("Not a valid item kind: {kind:?}");
|
||||
}
|
||||
DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
|
||||
ItemKind::Fn
|
||||
}
|
||||
DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
|
||||
ItemKind::Const
|
||||
}
|
||||
DefKind::Static { .. } => ItemKind::Static,
|
||||
DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
|
||||
DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
||||
pub trait Stable<'cx>: PointeeSized {
|
||||
/// The stable representation of the type implementing Stable.
|
||||
type T;
|
||||
/// Converts an object to the equivalent Stable MIR representation.
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T;
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for &T
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = T::T;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
(*self).stable(tables)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for Option<T>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = Option<T::T>;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
self.as_ref().map(|value| value.stable(tables))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
E: Stable<'tcx>,
|
||||
{
|
||||
type T = Result<T::T, E::T>;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
match self {
|
||||
Ok(val) => Ok(val.stable(tables)),
|
||||
Err(error) => Err(error.stable(tables)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for &[T]
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = Vec<T::T>;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
self.iter().map(|e| e.stable(tables)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, U> Stable<'tcx> for (T, U)
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
U: Stable<'tcx>,
|
||||
{
|
||||
type T = (T::T, U::T);
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
(self.0.stable(tables), self.1.stable(tables))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for RangeInclusive<T>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = RangeInclusive<T::T>;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
RangeInclusive::new(self.start().stable(tables), self.end().stable(tables))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use serde::Serialize;
|
|||
use stable_mir::compiler_interface::with;
|
||||
use stable_mir::mir::FieldIdx;
|
||||
use stable_mir::target::{MachineInfo, MachineSize as Size};
|
||||
use stable_mir::ty::{Align, IndexedVal, Ty, VariantIdx};
|
||||
use stable_mir::ty::{Align, Ty, VariantIdx};
|
||||
use stable_mir::{Error, Opaque, error};
|
||||
|
||||
use crate::stable_mir;
|
||||
|
|
@ -119,7 +119,7 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
impl IndexedVal for Layout {
|
||||
impl stable_mir::IndexedVal for Layout {
|
||||
fn to_val(index: usize) -> Self {
|
||||
Layout(index)
|
||||
}
|
||||
|
|
|
|||
77
compiler/rustc_smir/src/stable_mir/alloc.rs
Normal file
77
compiler/rustc_smir/src/stable_mir/alloc.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//! Memory allocation implementation for StableMIR.
|
||||
//!
|
||||
//! This module is responsible for constructing stable components.
|
||||
//! All operations requiring rustc queries must be delegated
|
||||
//! to `rustc_smir::alloc` to maintain stability guarantees.
|
||||
|
||||
use rustc_abi::Align;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::AllocRange;
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_smir::{Tables, alloc};
|
||||
|
||||
use super::Error;
|
||||
use super::compiler_interface::BridgeTys;
|
||||
use super::mir::Mutability;
|
||||
use super::ty::{Allocation, ProvenanceMap};
|
||||
use super::unstable::Stable;
|
||||
use crate::rustc_smir;
|
||||
|
||||
/// Creates new empty `Allocation` from given `Align`.
|
||||
fn new_empty_allocation(align: Align) -> Allocation {
|
||||
Allocation {
|
||||
bytes: Vec::new(),
|
||||
provenance: ProvenanceMap { ptrs: Vec::new() },
|
||||
align: align.bytes(),
|
||||
mutability: Mutability::Not,
|
||||
}
|
||||
}
|
||||
|
||||
// We need this method instead of a Stable implementation
|
||||
// because we need to get `Ty` of the const we are trying to create, to do that
|
||||
// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
|
||||
#[allow(rustc::usage_of_qualified_ty)]
|
||||
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>,
|
||||
) -> Allocation {
|
||||
try_new_allocation(ty, const_value, tables, cx)
|
||||
.unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
|
||||
}
|
||||
|
||||
#[allow(rustc::usage_of_qualified_ty)]
|
||||
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>,
|
||||
) -> Result<Allocation, Error> {
|
||||
let layout = alloc::create_ty_and_layout(cx, ty).map_err(|e| Error::from_internal(e))?;
|
||||
match const_value {
|
||||
ConstValue::Scalar(scalar) => {
|
||||
alloc::try_new_scalar(layout, scalar, cx).map(|alloc| alloc.stable(tables, cx))
|
||||
}
|
||||
ConstValue::ZeroSized => Ok(new_empty_allocation(layout.align.abi)),
|
||||
ConstValue::Slice { data, meta } => {
|
||||
alloc::try_new_slice(layout, data, meta, cx).map(|alloc| alloc.stable(tables, cx))
|
||||
}
|
||||
ConstValue::Indirect { alloc_id, offset } => {
|
||||
let alloc = alloc::try_new_indirect(alloc_id, cx);
|
||||
use rustc_smir::context::SmirAllocRange;
|
||||
Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an `Allocation` only from information within the `AllocRange`.
|
||||
pub(super) fn allocation_filter<'tcx>(
|
||||
alloc: &rustc_middle::mir::interpret::Allocation,
|
||||
alloc_range: AllocRange,
|
||||
tables: &mut Tables<'tcx, BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, BridgeTys>,
|
||||
) -> Allocation {
|
||||
alloc::allocation_filter(alloc, alloc_range, tables, cx)
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,10 @@
|
|||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::{fmt, io};
|
||||
|
||||
use rustc_smir::bridge::SmirError;
|
||||
|
||||
use crate::rustc_smir;
|
||||
|
||||
macro_rules! error {
|
||||
($fmt: literal $(,)?) => { Error(format!($fmt)) };
|
||||
($fmt: literal, $($arg:tt)*) => { Error(format!($fmt, $($arg)*)) };
|
||||
|
|
@ -30,10 +34,14 @@ pub enum CompilerError<T> {
|
|||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Error(pub(crate) String);
|
||||
|
||||
impl Error {
|
||||
pub fn new(msg: String) -> Self {
|
||||
impl SmirError for Error {
|
||||
fn new(msg: String) -> Self {
|
||||
Self(msg)
|
||||
}
|
||||
|
||||
fn from_internal<T: Debug>(err: T) -> Self {
|
||||
Self(format!("{err:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Error {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use std::io::Read;
|
|||
use serde::Serialize;
|
||||
use stable_mir::mir::mono::{Instance, StaticDef};
|
||||
use stable_mir::target::{Endian, MachineInfo};
|
||||
use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
|
||||
use stable_mir::{Error, with};
|
||||
use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, Ty};
|
||||
use stable_mir::{Error, IndexedVal, with};
|
||||
|
||||
use crate::stable_mir;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
use std::fmt::{Debug, Formatter};
|
||||
use std::io;
|
||||
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use serde::Serialize;
|
||||
use stable_mir::abi::FnAbi;
|
||||
use stable_mir::crate_def::CrateDef;
|
||||
use stable_mir::mir::Body;
|
||||
use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
|
||||
use stable_mir::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
|
||||
use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty};
|
||||
use stable_mir::{CrateItem, DefId, Error, IndexedVal, ItemKind, Opaque, Symbol, with};
|
||||
|
||||
use crate::stable_mir;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum MonoItem {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use fmt::{Display, Formatter};
|
|||
use stable_mir::mir::{
|
||||
Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
|
||||
};
|
||||
use stable_mir::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
|
||||
use stable_mir::{Body, CrateDef, Mutability, with};
|
||||
use stable_mir::ty::{AdtKind, AssocKind, MirConst, Ty, TyConst};
|
||||
use stable_mir::{Body, CrateDef, IndexedVal, Mutability, with};
|
||||
|
||||
use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
|
||||
use crate::stable_mir;
|
||||
|
|
|
|||
|
|
@ -27,17 +27,25 @@
|
|||
use std::fmt::Debug;
|
||||
use std::{fmt, io};
|
||||
|
||||
pub(crate) use rustc_smir::IndexedVal;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use serde::Serialize;
|
||||
use stable_mir::compiler_interface::with;
|
||||
pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
|
||||
pub use stable_mir::error::*;
|
||||
use stable_mir::mir::mono::StaticDef;
|
||||
use stable_mir::mir::{Body, Mutability};
|
||||
use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
|
||||
use stable_mir::ty::{
|
||||
AssocItem, FnDef, ForeignModuleDef, ImplDef, ProvenanceMap, Span, TraitDef, Ty,
|
||||
};
|
||||
use stable_mir::unstable::Stable;
|
||||
|
||||
use crate::stable_mir;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
pub mod abi;
|
||||
mod alloc;
|
||||
pub(crate) mod unstable;
|
||||
#[macro_use]
|
||||
pub mod crate_def;
|
||||
pub mod compiler_interface;
|
||||
|
|
@ -237,3 +245,60 @@ impl std::fmt::Debug for Opaque {
|
|||
pub fn opaque<T: Debug>(value: &T) -> Opaque {
|
||||
Opaque(format!("{value:?}"))
|
||||
}
|
||||
|
||||
macro_rules! bridge_impl {
|
||||
($name: ident, $ty: ty) => {
|
||||
impl rustc_smir::bridge::$name<compiler_interface::BridgeTys> for $ty {
|
||||
fn new(def: stable_mir::DefId) -> Self {
|
||||
Self(def)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bridge_impl!(CrateItem, stable_mir::CrateItem);
|
||||
bridge_impl!(AdtDef, stable_mir::ty::AdtDef);
|
||||
bridge_impl!(ForeignModuleDef, stable_mir::ty::ForeignModuleDef);
|
||||
bridge_impl!(ForeignDef, stable_mir::ty::ForeignDef);
|
||||
bridge_impl!(FnDef, stable_mir::ty::FnDef);
|
||||
bridge_impl!(ClosureDef, stable_mir::ty::ClosureDef);
|
||||
bridge_impl!(CoroutineDef, stable_mir::ty::CoroutineDef);
|
||||
bridge_impl!(CoroutineClosureDef, stable_mir::ty::CoroutineClosureDef);
|
||||
bridge_impl!(AliasDef, stable_mir::ty::AliasDef);
|
||||
bridge_impl!(ParamDef, stable_mir::ty::ParamDef);
|
||||
bridge_impl!(BrNamedDef, stable_mir::ty::BrNamedDef);
|
||||
bridge_impl!(TraitDef, stable_mir::ty::TraitDef);
|
||||
bridge_impl!(GenericDef, stable_mir::ty::GenericDef);
|
||||
bridge_impl!(ConstDef, stable_mir::ty::ConstDef);
|
||||
bridge_impl!(ImplDef, stable_mir::ty::ImplDef);
|
||||
bridge_impl!(RegionDef, stable_mir::ty::RegionDef);
|
||||
bridge_impl!(CoroutineWitnessDef, stable_mir::ty::CoroutineWitnessDef);
|
||||
bridge_impl!(AssocDef, stable_mir::ty::AssocDef);
|
||||
bridge_impl!(OpaqueDef, stable_mir::ty::OpaqueDef);
|
||||
bridge_impl!(StaticDef, stable_mir::mir::mono::StaticDef);
|
||||
|
||||
impl rustc_smir::bridge::Prov<compiler_interface::BridgeTys> for stable_mir::ty::Prov {
|
||||
fn new(aid: stable_mir::mir::alloc::AllocId) -> Self {
|
||||
Self(aid)
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_smir::bridge::Allocation<compiler_interface::BridgeTys> for stable_mir::ty::Allocation {
|
||||
fn new<'tcx>(
|
||||
bytes: Vec<Option<u8>>,
|
||||
ptrs: Vec<(usize, rustc_middle::mir::interpret::AllocId)>,
|
||||
align: u64,
|
||||
mutability: rustc_middle::mir::Mutability,
|
||||
tables: &mut Tables<'tcx, compiler_interface::BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, compiler_interface::BridgeTys>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bytes,
|
||||
provenance: ProvenanceMap {
|
||||
ptrs: ptrs.iter().map(|(i, aid)| (*i, tables.prov(*aid))).collect(),
|
||||
},
|
||||
align,
|
||||
mutability: mutability.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType};
|
|||
use stable_mir::mir::alloc::{AllocId, read_target_int, read_target_uint};
|
||||
use stable_mir::mir::mono::StaticDef;
|
||||
use stable_mir::target::MachineInfo;
|
||||
use stable_mir::{Filename, Opaque};
|
||||
use stable_mir::{Filename, IndexedVal, Opaque};
|
||||
|
||||
use super::abi::ReprOptions;
|
||||
use super::mir::{Body, Mutability, Safety};
|
||||
|
|
@ -298,6 +298,12 @@ pub struct LineInfo {
|
|||
pub end_col: usize,
|
||||
}
|
||||
|
||||
impl LineInfo {
|
||||
pub fn from(lines: (usize, usize, usize, usize)) -> Self {
|
||||
LineInfo { start_line: lines.0, start_col: lines.1, end_line: lines.2, end_col: lines.3 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum TyKind {
|
||||
RigidTy(RigidTy),
|
||||
|
|
@ -1557,15 +1563,9 @@ pub enum PredicatePolarity {
|
|||
Negative,
|
||||
}
|
||||
|
||||
pub trait IndexedVal {
|
||||
fn to_val(index: usize) -> Self;
|
||||
|
||||
fn to_index(&self) -> usize;
|
||||
}
|
||||
|
||||
macro_rules! index_impl {
|
||||
($name:ident) => {
|
||||
impl IndexedVal for $name {
|
||||
impl stable_mir::IndexedVal for $name {
|
||||
fn to_val(index: usize) -> Self {
|
||||
$name(index)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,55 +5,76 @@
|
|||
|
||||
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
|
||||
|
||||
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt};
|
||||
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_span::Symbol;
|
||||
use stable_mir::abi::Layout;
|
||||
use stable_mir::compiler_interface::BridgeTys;
|
||||
use stable_mir::mir::alloc::AllocId;
|
||||
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
|
||||
use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp};
|
||||
use stable_mir::ty::{
|
||||
Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind,
|
||||
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
|
||||
GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy,
|
||||
Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
|
||||
GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span,
|
||||
TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
|
||||
};
|
||||
use stable_mir::{CrateItem, CrateNum, DefId};
|
||||
use stable_mir::unstable::{InternalCx, RustcInternal};
|
||||
use stable_mir::{CrateItem, CrateNum, DefId, IndexedVal};
|
||||
|
||||
use super::RustcInternal;
|
||||
use crate::rustc_smir::Tables;
|
||||
use crate::stable_mir;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
impl RustcInternal for CrateItem {
|
||||
type T<'tcx> = rustc_span::def_id::DefId;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
self.0.internal(tables, tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for CrateNum {
|
||||
type T<'tcx> = rustc_span::def_id::CrateNum;
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
rustc_span::def_id::CrateNum::from_usize(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for DefId {
|
||||
type T<'tcx> = rustc_span::def_id::DefId;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.def_ids[*self]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for GenericArgs {
|
||||
type T<'tcx> = rustc_ty::GenericArgsRef<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx)))
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
InternalCx::mk_args_from_iter(tcx, self.0.iter().map(|arg| arg.internal(tables, tcx)))
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for GenericArgKind {
|
||||
type T<'tcx> = rustc_ty::GenericArg<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
let arg: rustc_ty::GenericArg<'tcx> = match self {
|
||||
GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(),
|
||||
GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(),
|
||||
|
|
@ -65,29 +86,45 @@ impl RustcInternal for GenericArgKind {
|
|||
|
||||
impl RustcInternal for Region {
|
||||
type T<'tcx> = rustc_ty::Region<'tcx>;
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
// Cannot recover region. Use erased for now.
|
||||
tcx.lifetimes.re_erased
|
||||
tcx.lifetimes_re_erased()
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Ty {
|
||||
type T<'tcx> = InternalTy<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.types[*self]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for TyConst {
|
||||
type T<'tcx> = InternalConst<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.ty_consts[self.id]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Pattern {
|
||||
type T<'tcx> = rustc_ty::Pattern<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.mk_pat(match self {
|
||||
Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range {
|
||||
start: start.as_ref().unwrap().internal(tables, tcx),
|
||||
|
|
@ -100,7 +137,11 @@ impl RustcInternal for Pattern {
|
|||
impl RustcInternal for RigidTy {
|
||||
type T<'tcx> = rustc_ty::TyKind<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
RigidTy::Bool => rustc_ty::TyKind::Bool,
|
||||
RigidTy::Char => rustc_ty::TyKind::Char,
|
||||
|
|
@ -164,7 +205,11 @@ impl RustcInternal for RigidTy {
|
|||
impl RustcInternal for IntTy {
|
||||
type T<'tcx> = rustc_ty::IntTy;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
IntTy::Isize => rustc_ty::IntTy::Isize,
|
||||
IntTy::I8 => rustc_ty::IntTy::I8,
|
||||
|
|
@ -179,7 +224,11 @@ impl RustcInternal for IntTy {
|
|||
impl RustcInternal for UintTy {
|
||||
type T<'tcx> = rustc_ty::UintTy;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
UintTy::Usize => rustc_ty::UintTy::Usize,
|
||||
UintTy::U8 => rustc_ty::UintTy::U8,
|
||||
|
|
@ -194,7 +243,11 @@ impl RustcInternal for UintTy {
|
|||
impl RustcInternal for FloatTy {
|
||||
type T<'tcx> = rustc_ty::FloatTy;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
FloatTy::F16 => rustc_ty::FloatTy::F16,
|
||||
FloatTy::F32 => rustc_ty::FloatTy::F32,
|
||||
|
|
@ -207,7 +260,11 @@ impl RustcInternal for FloatTy {
|
|||
impl RustcInternal for Mutability {
|
||||
type T<'tcx> = rustc_ty::Mutability;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
Mutability::Not => rustc_ty::Mutability::Not,
|
||||
Mutability::Mut => rustc_ty::Mutability::Mut,
|
||||
|
|
@ -218,7 +275,11 @@ impl RustcInternal for Mutability {
|
|||
impl RustcInternal for Movability {
|
||||
type T<'tcx> = rustc_ty::Movability;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
Movability::Static => rustc_ty::Movability::Static,
|
||||
Movability::Movable => rustc_ty::Movability::Movable,
|
||||
|
|
@ -229,7 +290,11 @@ impl RustcInternal for Movability {
|
|||
impl RustcInternal for RawPtrKind {
|
||||
type T<'tcx> = rustc_middle::mir::RawPtrKind;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
RawPtrKind::Mut => rustc_middle::mir::RawPtrKind::Mut,
|
||||
RawPtrKind::Const => rustc_middle::mir::RawPtrKind::Const,
|
||||
|
|
@ -241,7 +306,11 @@ impl RustcInternal for RawPtrKind {
|
|||
impl RustcInternal for FnSig {
|
||||
type T<'tcx> = rustc_ty::FnSig<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(rustc_ty::FnSig {
|
||||
inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)),
|
||||
c_variadic: self.c_variadic,
|
||||
|
|
@ -255,7 +324,11 @@ impl RustcInternal for FnSig {
|
|||
impl RustcInternal for VariantIdx {
|
||||
type T<'tcx> = rustc_abi::VariantIdx;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
rustc_abi::VariantIdx::from(self.to_index())
|
||||
}
|
||||
}
|
||||
|
|
@ -263,14 +336,22 @@ impl RustcInternal for VariantIdx {
|
|||
impl RustcInternal for VariantDef {
|
||||
type T<'tcx> = &'tcx rustc_ty::VariantDef;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for MirConst {
|
||||
type T<'tcx> = rustc_middle::mir::Const<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
let constant = tables.mir_consts[self.id];
|
||||
match constant {
|
||||
rustc_middle::mir::Const::Ty(ty, ct) => {
|
||||
|
|
@ -292,7 +373,11 @@ impl RustcInternal for MirConst {
|
|||
impl RustcInternal for MonoItem {
|
||||
type T<'tcx> = rustc_middle::mir::mono::MonoItem<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use rustc_middle::mir::mono as rustc_mono;
|
||||
match self {
|
||||
MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, tcx)),
|
||||
|
|
@ -307,7 +392,11 @@ impl RustcInternal for MonoItem {
|
|||
impl RustcInternal for Instance {
|
||||
type T<'tcx> = rustc_ty::Instance<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.instances[self.def]).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -315,7 +404,11 @@ impl RustcInternal for Instance {
|
|||
impl RustcInternal for StaticDef {
|
||||
type T<'tcx> = rustc_span::def_id::DefId;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
self.0.internal(tables, tcx)
|
||||
}
|
||||
}
|
||||
|
|
@ -328,7 +421,11 @@ where
|
|||
{
|
||||
type T<'tcx> = rustc_ty::Binder<'tcx, T::T<'tcx>>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
rustc_ty::Binder::bind_with_vars(
|
||||
self.value.internal(tables, tcx),
|
||||
tcx.mk_bound_variable_kinds_from_iter(
|
||||
|
|
@ -341,7 +438,11 @@ where
|
|||
impl RustcInternal for BoundVariableKind {
|
||||
type T<'tcx> = rustc_ty::BoundVariableKind;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
|
||||
BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
|
||||
|
|
@ -366,7 +467,11 @@ impl RustcInternal for BoundVariableKind {
|
|||
impl RustcInternal for DynKind {
|
||||
type T<'tcx> = rustc_ty::DynKind;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
DynKind::Dyn => rustc_ty::DynKind::Dyn,
|
||||
}
|
||||
|
|
@ -376,7 +481,11 @@ impl RustcInternal for DynKind {
|
|||
impl RustcInternal for ExistentialPredicate {
|
||||
type T<'tcx> = rustc_ty::ExistentialPredicate<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
ExistentialPredicate::Trait(trait_ref) => {
|
||||
rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx))
|
||||
|
|
@ -394,9 +503,13 @@ impl RustcInternal for ExistentialPredicate {
|
|||
impl RustcInternal for ExistentialProjection {
|
||||
type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
rustc_ty::ExistentialProjection::new_from_args(
|
||||
tcx,
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use rustc_smir::context::SmirExistentialProjection;
|
||||
tcx.new_from_args(
|
||||
self.def_id.0.internal(tables, tcx),
|
||||
self.generic_args.internal(tables, tcx),
|
||||
self.term.internal(tables, tcx),
|
||||
|
|
@ -407,7 +520,11 @@ impl RustcInternal for ExistentialProjection {
|
|||
impl RustcInternal for TermKind {
|
||||
type T<'tcx> = rustc_ty::Term<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
TermKind::Type(ty) => ty.internal(tables, tcx).into(),
|
||||
TermKind::Const(cnst) => cnst.internal(tables, tcx).into(),
|
||||
|
|
@ -418,9 +535,13 @@ impl RustcInternal for TermKind {
|
|||
impl RustcInternal for ExistentialTraitRef {
|
||||
type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
rustc_ty::ExistentialTraitRef::new_from_args(
|
||||
tcx,
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use rustc_smir::context::SmirExistentialTraitRef;
|
||||
tcx.new_from_args(
|
||||
self.def_id.0.internal(tables, tcx),
|
||||
self.generic_args.internal(tables, tcx),
|
||||
)
|
||||
|
|
@ -430,18 +551,23 @@ impl RustcInternal for ExistentialTraitRef {
|
|||
impl RustcInternal for TraitRef {
|
||||
type T<'tcx> = rustc_ty::TraitRef<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
rustc_ty::TraitRef::new_from_args(
|
||||
tcx,
|
||||
self.def_id.0.internal(tables, tcx),
|
||||
self.args().internal(tables, tcx),
|
||||
)
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use rustc_smir::context::SmirTraitRef;
|
||||
tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for AllocId {
|
||||
type T<'tcx> = rustc_middle::mir::interpret::AllocId;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.alloc_ids[*self]).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -449,7 +575,11 @@ impl RustcInternal for AllocId {
|
|||
impl RustcInternal for ClosureKind {
|
||||
type T<'tcx> = rustc_ty::ClosureKind;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
|
||||
ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
|
||||
|
|
@ -460,15 +590,23 @@ impl RustcInternal for ClosureKind {
|
|||
|
||||
impl RustcInternal for AdtDef {
|
||||
type T<'tcx> = rustc_ty::AdtDef<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.adt_def(self.0.internal(tables, tcx))
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
InternalCx::adt_def(tcx, self.0.internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Abi {
|
||||
type T<'tcx> = rustc_abi::ExternAbi;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match *self {
|
||||
Abi::Rust => rustc_abi::ExternAbi::Rust,
|
||||
Abi::C { unwind } => rustc_abi::ExternAbi::C { unwind },
|
||||
|
|
@ -504,7 +642,11 @@ impl RustcInternal for Abi {
|
|||
impl RustcInternal for Safety {
|
||||
type T<'tcx> = rustc_hir::Safety;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
Safety::Unsafe => rustc_hir::Safety::Unsafe,
|
||||
Safety::Safe => rustc_hir::Safety::Safe,
|
||||
|
|
@ -514,15 +656,23 @@ impl RustcInternal for Safety {
|
|||
impl RustcInternal for Span {
|
||||
type T<'tcx> = rustc_span::Span;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tables[*self]
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tables.spans[*self]
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Layout {
|
||||
type T<'tcx> = rustc_abi::Layout<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.layouts[*self]).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -530,7 +680,11 @@ impl RustcInternal for Layout {
|
|||
impl RustcInternal for Place {
|
||||
type T<'tcx> = rustc_middle::mir::Place<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
rustc_middle::mir::Place {
|
||||
local: rustc_middle::mir::Local::from_usize(self.local),
|
||||
projection: tcx.mk_place_elems(&self.projection.internal(tables, tcx)),
|
||||
|
|
@ -541,7 +695,11 @@ impl RustcInternal for Place {
|
|||
impl RustcInternal for ProjectionElem {
|
||||
type T<'tcx> = rustc_middle::mir::PlaceElem<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
ProjectionElem::Deref => rustc_middle::mir::PlaceElem::Deref,
|
||||
ProjectionElem::Field(idx, ty) => {
|
||||
|
|
@ -574,7 +732,11 @@ impl RustcInternal for ProjectionElem {
|
|||
impl RustcInternal for BinOp {
|
||||
type T<'tcx> = rustc_middle::mir::BinOp;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
BinOp::Add => rustc_middle::mir::BinOp::Add,
|
||||
BinOp::AddUnchecked => rustc_middle::mir::BinOp::AddUnchecked,
|
||||
|
|
@ -606,7 +768,11 @@ impl RustcInternal for BinOp {
|
|||
impl RustcInternal for UnOp {
|
||||
type T<'tcx> = rustc_middle::mir::UnOp;
|
||||
|
||||
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'_, BridgeTys>,
|
||||
_tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
match self {
|
||||
UnOp::Not => rustc_middle::mir::UnOp::Not,
|
||||
UnOp::Neg => rustc_middle::mir::UnOp::Neg,
|
||||
|
|
@ -621,7 +787,11 @@ where
|
|||
{
|
||||
type T<'tcx> = T::T<'tcx>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
(*self).internal(tables, tcx)
|
||||
}
|
||||
}
|
||||
|
|
@ -632,7 +802,11 @@ where
|
|||
{
|
||||
type T<'tcx> = Option<T::T<'tcx>>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
self.as_ref().map(|inner| inner.internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
|
|
@ -643,7 +817,11 @@ where
|
|||
{
|
||||
type T<'tcx> = Vec<T::T<'tcx>>;
|
||||
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
self.iter().map(|e| e.internal(tables, tcx)).collect()
|
||||
}
|
||||
}
|
||||
111
compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs
Normal file
111
compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
//! This module holds the logic to convert rustc internal ADTs into stable mir 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_smir functions.
|
||||
//!
|
||||
//! For contributors, please make sure to avoid calling rustc's internal functions and queries.
|
||||
//! These should be done via `rustc_smir` APIs, but it's possible to access ADT fields directly.
|
||||
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use stable_mir::compiler_interface::BridgeTys;
|
||||
|
||||
use super::Stable;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
mod internal;
|
||||
mod stable;
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for &T
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = T::T;
|
||||
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
(*self).stable(tables, cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for Option<T>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = Option<T::T>;
|
||||
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.as_ref().map(|value| value.stable(tables, cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
E: Stable<'tcx>,
|
||||
{
|
||||
type T = Result<T::T, E::T>;
|
||||
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
Ok(val) => Ok(val.stable(tables, cx)),
|
||||
Err(error) => Err(error.stable(tables, cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for &[T]
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = Vec<T::T>;
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.iter().map(|e| e.stable(tables, cx)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, U> Stable<'tcx> for (T, U)
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
U: Stable<'tcx>,
|
||||
{
|
||||
type T = (T::T, U::T);
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
(self.0.stable(tables, cx), self.1.stable(tables, cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Stable<'tcx> for RangeInclusive<T>
|
||||
where
|
||||
T: Stable<'tcx>,
|
||||
{
|
||||
type T = RangeInclusive<T::T>;
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -4,22 +4,25 @@
|
|||
|
||||
use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
|
||||
use rustc_middle::ty;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_target::callconv;
|
||||
use stable_mir::abi::{
|
||||
AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength,
|
||||
IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar,
|
||||
TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange,
|
||||
};
|
||||
use stable_mir::opaque;
|
||||
use stable_mir::compiler_interface::BridgeTys;
|
||||
use stable_mir::target::MachineSize as Size;
|
||||
use stable_mir::ty::{Align, IndexedVal, VariantIdx};
|
||||
use stable_mir::ty::{Align, VariantIdx};
|
||||
use stable_mir::unstable::Stable;
|
||||
use stable_mir::{IndexedVal, opaque};
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::stable_mir;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
|
||||
type T = VariantIdx;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
VariantIdx::to_val(self.as_usize())
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +30,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
|
||||
type T = stable_mir::target::Endian;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Endian::Little => stable_mir::target::Endian::Little,
|
||||
rustc_abi::Endian::Big => stable_mir::target::Endian::Big,
|
||||
|
|
@ -38,29 +41,41 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
|
||||
type T = TyAndLayout;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
TyAndLayout { ty: self.ty.stable(tables), layout: self.layout.stable(tables) }
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
|
||||
type T = Layout;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
tables.layout_id(tables.tcx.lift(*self).unwrap())
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.layout_id(cx.lift(*self).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
|
||||
type T = LayoutShape;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
LayoutShape {
|
||||
fields: self.fields.stable(tables),
|
||||
variants: self.variants.stable(tables),
|
||||
abi: self.backend_repr.stable(tables),
|
||||
abi_align: self.align.abi.stable(tables),
|
||||
size: self.size.stable(tables),
|
||||
fields: self.fields.stable(tables, cx),
|
||||
variants: self.variants.stable(tables, cx),
|
||||
abi: self.backend_repr.stable(tables, cx),
|
||||
abi_align: self.align.abi.stable(tables, cx),
|
||||
size: self.size.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,14 +83,18 @@ impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi
|
|||
impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
|
||||
type T = FnAbi;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
assert!(self.args.len() >= self.fixed_count as usize);
|
||||
assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
|
||||
FnAbi {
|
||||
args: self.args.as_ref().stable(tables),
|
||||
ret: self.ret.stable(tables),
|
||||
args: self.args.as_ref().stable(tables, cx),
|
||||
ret: self.ret.stable(tables, cx),
|
||||
fixed_count: self.fixed_count,
|
||||
conv: self.conv.stable(tables),
|
||||
conv: self.conv.stable(tables, cx),
|
||||
c_variadic: self.c_variadic,
|
||||
}
|
||||
}
|
||||
|
|
@ -84,11 +103,15 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
|
|||
impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
|
||||
type T = ArgAbi;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ArgAbi {
|
||||
ty: self.layout.ty.stable(tables),
|
||||
layout: self.layout.layout.stable(tables),
|
||||
mode: self.mode.stable(tables),
|
||||
ty: self.layout.ty.stable(tables, cx),
|
||||
layout: self.layout.layout.stable(tables, cx),
|
||||
mode: self.mode.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +119,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
|
|||
impl<'tcx> Stable<'tcx> for CanonAbi {
|
||||
type T = CallConvention;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
CanonAbi::C => CallConvention::C,
|
||||
CanonAbi::Rust => CallConvention::Rust,
|
||||
|
|
@ -132,7 +155,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi {
|
|||
impl<'tcx> Stable<'tcx> for callconv::PassMode {
|
||||
type T = PassMode;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
callconv::PassMode::Ignore => PassMode::Ignore,
|
||||
callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
|
||||
|
|
@ -154,15 +177,19 @@ impl<'tcx> Stable<'tcx> for callconv::PassMode {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
|
||||
type T = FieldsShape;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
|
||||
rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
|
||||
rustc_abi::FieldsShape::Array { stride, count } => {
|
||||
FieldsShape::Array { stride: stride.stable(tables), count: *count }
|
||||
FieldsShape::Array { stride: stride.stable(tables, cx), count: *count }
|
||||
}
|
||||
rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
|
||||
FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) }
|
||||
FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -171,18 +198,22 @@ impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
|
||||
type T = VariantsShape;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Variants::Single { index } => {
|
||||
VariantsShape::Single { index: index.stable(tables) }
|
||||
VariantsShape::Single { index: index.stable(tables, cx) }
|
||||
}
|
||||
rustc_abi::Variants::Empty => VariantsShape::Empty,
|
||||
rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
|
||||
VariantsShape::Multiple {
|
||||
tag: tag.stable(tables),
|
||||
tag_encoding: tag_encoding.stable(tables),
|
||||
tag_field: tag_field.stable(tables),
|
||||
variants: variants.iter().as_slice().stable(tables),
|
||||
tag: tag.stable(tables, cx),
|
||||
tag_encoding: tag_encoding.stable(tables, cx),
|
||||
tag_field: tag_field.stable(tables, cx),
|
||||
variants: variants.iter().as_slice().stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,13 +223,17 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
|
||||
type T = TagEncoding;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
|
||||
rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
|
||||
TagEncoding::Niche {
|
||||
untagged_variant: untagged_variant.stable(tables),
|
||||
niche_variants: niche_variants.stable(tables),
|
||||
untagged_variant: untagged_variant.stable(tables, cx),
|
||||
niche_variants: niche_variants.stable(tables, cx),
|
||||
niche_start: *niche_start,
|
||||
}
|
||||
}
|
||||
|
|
@ -209,14 +244,18 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
|
||||
type T = ValueAbi;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match *self {
|
||||
rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
|
||||
rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
|
||||
rustc_abi::BackendRepr::ScalarPair(first, second) => {
|
||||
ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
|
||||
ValueAbi::ScalarPair(first.stable(tables, cx), second.stable(tables, cx))
|
||||
}
|
||||
rustc_abi::BackendRepr::SimdVector { element, count } => {
|
||||
ValueAbi::Vector { element: element.stable(tables), count }
|
||||
ValueAbi::Vector { element: element.stable(tables, cx), count }
|
||||
}
|
||||
rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
|
||||
}
|
||||
|
|
@ -226,7 +265,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Size {
|
||||
type T = Size;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
Size::from_bits(self.bits_usize())
|
||||
}
|
||||
}
|
||||
|
|
@ -234,7 +273,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Align {
|
||||
type T = Align;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.bytes()
|
||||
}
|
||||
}
|
||||
|
|
@ -242,13 +281,17 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Align {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
|
||||
type T = Scalar;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
|
||||
value: value.stable(tables),
|
||||
valid_range: valid_range.stable(tables),
|
||||
value: value.stable(tables, cx),
|
||||
valid_range: valid_range.stable(tables, cx),
|
||||
},
|
||||
rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) },
|
||||
rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,15 +299,19 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
|
||||
type T = Primitive;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Primitive::Int(length, signed) => {
|
||||
Primitive::Int { length: length.stable(tables), signed: *signed }
|
||||
Primitive::Int { length: length.stable(tables, cx), signed: *signed }
|
||||
}
|
||||
rustc_abi::Primitive::Float(length) => {
|
||||
Primitive::Float { length: length.stable(tables) }
|
||||
Primitive::Float { length: length.stable(tables, cx) }
|
||||
}
|
||||
rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
|
||||
rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +319,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
|
||||
type T = AddressSpace;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
AddressSpace(self.0)
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +327,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
|
||||
type T = IntegerLength;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Integer::I8 => IntegerLength::I8,
|
||||
rustc_abi::Integer::I16 => IntegerLength::I16,
|
||||
|
|
@ -294,7 +341,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Float {
|
||||
type T = FloatLength;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Float::F16 => FloatLength::F16,
|
||||
rustc_abi::Float::F32 => FloatLength::F32,
|
||||
|
|
@ -307,7 +354,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Float {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
|
||||
type T = WrappingRange;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
WrappingRange { start: self.start, end: self.end }
|
||||
}
|
||||
}
|
||||
|
|
@ -315,7 +362,11 @@ impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
|
||||
type T = ReprFlags;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'cx, BridgeTys>,
|
||||
_cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ReprFlags {
|
||||
is_simd: self.intersects(Self::IS_SIMD),
|
||||
is_c: self.intersects(Self::IS_C),
|
||||
|
|
@ -328,11 +379,15 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
|
||||
type T = IntegerType;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
|
||||
rustc_abi::IntegerType::Fixed(integer, signed) => {
|
||||
IntegerType::Fixed { length: integer.stable(tables), is_signed: *signed }
|
||||
IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -341,12 +396,16 @@ impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
|
||||
type T = ReprOptions;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ReprOptions {
|
||||
int: self.int.map(|int| int.stable(tables)),
|
||||
align: self.align.map(|align| align.stable(tables)),
|
||||
pack: self.pack.map(|pack| pack.stable(tables)),
|
||||
flags: self.flags.stable(tables),
|
||||
int: self.int.map(|int| int.stable(tables, cx)),
|
||||
align: self.align.map(|align| align.stable(tables, cx)),
|
||||
pack: self.pack.map(|pack| pack.stable(tables, cx)),
|
||||
flags: self.flags.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +1,67 @@
|
|||
//! Conversion of internal Rust compiler `mir` items to stable ones.
|
||||
|
||||
use rustc_middle::mir::interpret::alloc_range;
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::{bug, mir};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use stable_mir::compiler_interface::BridgeTys;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment};
|
||||
use stable_mir::ty::{Allocation, ConstantKind, MirConst};
|
||||
use stable_mir::{Error, opaque};
|
||||
use stable_mir::unstable::Stable;
|
||||
use stable_mir::{Error, alloc, opaque};
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables, alloc};
|
||||
use crate::stable_mir;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
||||
type T = stable_mir::mir::Body;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
stable_mir::mir::Body::new(
|
||||
self.basic_blocks
|
||||
.iter()
|
||||
.map(|block| stable_mir::mir::BasicBlock {
|
||||
terminator: block.terminator().stable(tables),
|
||||
terminator: block.terminator().stable(tables, cx),
|
||||
statements: block
|
||||
.statements
|
||||
.iter()
|
||||
.map(|statement| statement.stable(tables))
|
||||
.map(|statement| statement.stable(tables, cx))
|
||||
.collect(),
|
||||
})
|
||||
.collect(),
|
||||
self.local_decls
|
||||
.iter()
|
||||
.map(|decl| stable_mir::mir::LocalDecl {
|
||||
ty: decl.ty.stable(tables),
|
||||
span: decl.source_info.span.stable(tables),
|
||||
mutability: decl.mutability.stable(tables),
|
||||
ty: decl.ty.stable(tables, cx),
|
||||
span: decl.source_info.span.stable(tables, cx),
|
||||
mutability: decl.mutability.stable(tables, cx),
|
||||
})
|
||||
.collect(),
|
||||
self.arg_count,
|
||||
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
|
||||
self.spread_arg.stable(tables),
|
||||
self.span.stable(tables),
|
||||
self.var_debug_info.iter().map(|info| info.stable(tables, cx)).collect(),
|
||||
self.spread_arg.stable(tables, cx),
|
||||
self.span.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
|
||||
type T = stable_mir::mir::VarDebugInfo;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
stable_mir::mir::VarDebugInfo {
|
||||
name: self.name.to_string(),
|
||||
source_info: self.source_info.stable(tables),
|
||||
composite: self.composite.as_ref().map(|composite| composite.stable(tables)),
|
||||
value: self.value.stable(tables),
|
||||
source_info: self.source_info.stable(tables, cx),
|
||||
composite: self.composite.as_ref().map(|composite| composite.stable(tables, cx)),
|
||||
value: self.value.stable(tables, cx),
|
||||
argument_index: self.argument_index,
|
||||
}
|
||||
}
|
||||
|
|
@ -58,40 +69,59 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
|
||||
type T = stable_mir::mir::Statement;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
Statement {
|
||||
kind: self.kind.stable(tables, cx),
|
||||
span: self.source_info.span.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::SourceInfo {
|
||||
type T = stable_mir::mir::SourceInfo;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() }
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
stable_mir::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
|
||||
type T = stable_mir::mir::VarDebugInfoFragment;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
VarDebugInfoFragment {
|
||||
ty: self.ty.stable(tables),
|
||||
projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
|
||||
ty: self.ty.stable(tables, cx),
|
||||
projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
|
||||
type T = stable_mir::mir::VarDebugInfoContents;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::VarDebugInfoContents::Place(place) => {
|
||||
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
|
||||
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables, cx))
|
||||
}
|
||||
mir::VarDebugInfoContents::Const(const_operand) => {
|
||||
let op = ConstOperand {
|
||||
span: const_operand.span.stable(tables),
|
||||
span: const_operand.span.stable(tables, cx),
|
||||
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
|
||||
const_: const_operand.const_.stable(tables),
|
||||
const_: const_operand.const_.stable(tables, cx),
|
||||
};
|
||||
stable_mir::mir::VarDebugInfoContents::Const(op)
|
||||
}
|
||||
|
|
@ -101,53 +131,58 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
|
||||
type T = stable_mir::mir::StatementKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign(
|
||||
assign.0.stable(tables),
|
||||
assign.1.stable(tables),
|
||||
assign.0.stable(tables, cx),
|
||||
assign.1.stable(tables, cx),
|
||||
),
|
||||
mir::StatementKind::FakeRead(fake_read_place) => {
|
||||
stable_mir::mir::StatementKind::FakeRead(
|
||||
fake_read_place.0.stable(tables),
|
||||
fake_read_place.1.stable(tables),
|
||||
fake_read_place.0.stable(tables, cx),
|
||||
fake_read_place.1.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
mir::StatementKind::SetDiscriminant { place, variant_index } => {
|
||||
stable_mir::mir::StatementKind::SetDiscriminant {
|
||||
place: place.as_ref().stable(tables),
|
||||
variant_index: variant_index.stable(tables),
|
||||
place: place.as_ref().stable(tables, cx),
|
||||
variant_index: variant_index.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
mir::StatementKind::Deinit(place) => {
|
||||
stable_mir::mir::StatementKind::Deinit(place.stable(tables))
|
||||
stable_mir::mir::StatementKind::Deinit(place.stable(tables, cx))
|
||||
}
|
||||
|
||||
mir::StatementKind::StorageLive(place) => {
|
||||
stable_mir::mir::StatementKind::StorageLive(place.stable(tables))
|
||||
stable_mir::mir::StatementKind::StorageLive(place.stable(tables, cx))
|
||||
}
|
||||
|
||||
mir::StatementKind::StorageDead(place) => {
|
||||
stable_mir::mir::StatementKind::StorageDead(place.stable(tables))
|
||||
}
|
||||
mir::StatementKind::Retag(retag, place) => {
|
||||
stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables))
|
||||
stable_mir::mir::StatementKind::StorageDead(place.stable(tables, cx))
|
||||
}
|
||||
mir::StatementKind::Retag(retag, place) => stable_mir::mir::StatementKind::Retag(
|
||||
retag.stable(tables, cx),
|
||||
place.stable(tables, cx),
|
||||
),
|
||||
mir::StatementKind::PlaceMention(place) => {
|
||||
stable_mir::mir::StatementKind::PlaceMention(place.stable(tables))
|
||||
stable_mir::mir::StatementKind::PlaceMention(place.stable(tables, cx))
|
||||
}
|
||||
mir::StatementKind::AscribeUserType(place_projection, variance) => {
|
||||
stable_mir::mir::StatementKind::AscribeUserType {
|
||||
place: place_projection.as_ref().0.stable(tables),
|
||||
projections: place_projection.as_ref().1.stable(tables),
|
||||
variance: variance.stable(tables),
|
||||
place: place_projection.as_ref().0.stable(tables, cx),
|
||||
projections: place_projection.as_ref().1.stable(tables, cx),
|
||||
variance: variance.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
mir::StatementKind::Coverage(coverage) => {
|
||||
stable_mir::mir::StatementKind::Coverage(opaque(coverage))
|
||||
}
|
||||
mir::StatementKind::Intrinsic(intrinstic) => {
|
||||
stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables))
|
||||
stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables, cx))
|
||||
}
|
||||
mir::StatementKind::ConstEvalCounter => {
|
||||
stable_mir::mir::StatementKind::ConstEvalCounter
|
||||
|
|
@ -163,61 +198,68 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
|
||||
type T = stable_mir::mir::Rvalue;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::Rvalue::*;
|
||||
match self {
|
||||
Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
|
||||
Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables, cx)),
|
||||
Repeat(op, len) => {
|
||||
let len = len.stable(tables);
|
||||
stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
|
||||
let len = len.stable(tables, cx);
|
||||
stable_mir::mir::Rvalue::Repeat(op.stable(tables, cx), len)
|
||||
}
|
||||
Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
|
||||
region.stable(tables),
|
||||
kind.stable(tables),
|
||||
place.stable(tables),
|
||||
region.stable(tables, cx),
|
||||
kind.stable(tables, cx),
|
||||
place.stable(tables, cx),
|
||||
),
|
||||
ThreadLocalRef(def_id) => {
|
||||
stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
|
||||
}
|
||||
RawPtr(mutability, place) => {
|
||||
stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
|
||||
}
|
||||
Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
|
||||
RawPtr(mutability, place) => stable_mir::mir::Rvalue::AddressOf(
|
||||
mutability.stable(tables, cx),
|
||||
place.stable(tables, cx),
|
||||
),
|
||||
Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables, cx)),
|
||||
Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
|
||||
cast_kind.stable(tables),
|
||||
op.stable(tables),
|
||||
ty.stable(tables),
|
||||
cast_kind.stable(tables, cx),
|
||||
op.stable(tables, cx),
|
||||
ty.stable(tables, cx),
|
||||
),
|
||||
BinaryOp(bin_op, ops) => {
|
||||
if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
|
||||
stable_mir::mir::Rvalue::CheckedBinaryOp(
|
||||
bin_op.stable(tables),
|
||||
ops.0.stable(tables),
|
||||
ops.1.stable(tables),
|
||||
bin_op.stable(tables, cx),
|
||||
ops.0.stable(tables, cx),
|
||||
ops.1.stable(tables, cx),
|
||||
)
|
||||
} else {
|
||||
stable_mir::mir::Rvalue::BinaryOp(
|
||||
bin_op.stable(tables),
|
||||
ops.0.stable(tables),
|
||||
ops.1.stable(tables),
|
||||
bin_op.stable(tables, cx),
|
||||
ops.0.stable(tables, cx),
|
||||
ops.1.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
}
|
||||
NullaryOp(null_op, ty) => {
|
||||
stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables))
|
||||
}
|
||||
NullaryOp(null_op, ty) => stable_mir::mir::Rvalue::NullaryOp(
|
||||
null_op.stable(tables, cx),
|
||||
ty.stable(tables, cx),
|
||||
),
|
||||
UnaryOp(un_op, op) => {
|
||||
stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
|
||||
stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables, cx), op.stable(tables, cx))
|
||||
}
|
||||
Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
|
||||
Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables, cx)),
|
||||
Aggregate(agg_kind, operands) => {
|
||||
let operands = operands.iter().map(|op| op.stable(tables)).collect();
|
||||
stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
|
||||
let operands = operands.iter().map(|op| op.stable(tables, cx)).collect();
|
||||
stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands)
|
||||
}
|
||||
ShallowInitBox(op, ty) => {
|
||||
stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
|
||||
}
|
||||
CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
|
||||
ShallowInitBox(op, ty) => stable_mir::mir::Rvalue::ShallowInitBox(
|
||||
op.stable(tables, cx),
|
||||
ty.stable(tables, cx),
|
||||
),
|
||||
CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables, cx)),
|
||||
WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Mutability {
|
||||
type T = stable_mir::mir::Mutability;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_hir::Mutability::*;
|
||||
match *self {
|
||||
Not => stable_mir::mir::Mutability::Not,
|
||||
|
|
@ -236,7 +278,7 @@ impl<'tcx> Stable<'tcx> for mir::Mutability {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
|
||||
type T = stable_mir::mir::RawPtrKind;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use mir::RawPtrKind::*;
|
||||
match *self {
|
||||
Const => stable_mir::mir::RawPtrKind::Const,
|
||||
|
|
@ -248,19 +290,23 @@ impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::BorrowKind {
|
||||
type T = stable_mir::mir::BorrowKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::BorrowKind::*;
|
||||
match *self {
|
||||
Shared => stable_mir::mir::BorrowKind::Shared,
|
||||
Fake(kind) => stable_mir::mir::BorrowKind::Fake(kind.stable(tables)),
|
||||
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
|
||||
Fake(kind) => stable_mir::mir::BorrowKind::Fake(kind.stable(tables, cx)),
|
||||
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables, cx) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
|
||||
type T = stable_mir::mir::MutBorrowKind;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::MutBorrowKind::*;
|
||||
match *self {
|
||||
Default => stable_mir::mir::MutBorrowKind::Default,
|
||||
|
|
@ -272,7 +318,7 @@ impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
|
||||
type T = stable_mir::mir::FakeBorrowKind;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::FakeBorrowKind::*;
|
||||
match *self {
|
||||
Deep => stable_mir::mir::FakeBorrowKind::Deep,
|
||||
|
|
@ -283,13 +329,17 @@ impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
|
||||
type T = stable_mir::mir::NullOp;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::NullOp::*;
|
||||
match self {
|
||||
SizeOf => stable_mir::mir::NullOp::SizeOf,
|
||||
AlignOf => stable_mir::mir::NullOp::AlignOf,
|
||||
OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
|
||||
indices.iter().map(|idx| idx.stable(tables)).collect(),
|
||||
indices.iter().map(|idx| idx.stable(tables, cx)).collect(),
|
||||
),
|
||||
UbChecks => stable_mir::mir::NullOp::UbChecks,
|
||||
ContractChecks => stable_mir::mir::NullOp::ContractChecks,
|
||||
|
|
@ -299,12 +349,18 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::CastKind {
|
||||
type T = stable_mir::mir::CastKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::CastKind::*;
|
||||
match self {
|
||||
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
|
||||
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
|
||||
PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
|
||||
PointerCoercion(c, _) => {
|
||||
stable_mir::mir::CastKind::PointerCoercion(c.stable(tables, cx))
|
||||
}
|
||||
IntToInt => stable_mir::mir::CastKind::IntToInt,
|
||||
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
|
||||
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
|
||||
|
|
@ -318,7 +374,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
|
||||
type T = stable_mir::mir::FakeReadCause;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::FakeReadCause::*;
|
||||
match self {
|
||||
ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard,
|
||||
|
|
@ -334,12 +390,16 @@ impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
|
||||
type T = stable_mir::mir::Operand;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::Operand::*;
|
||||
match self {
|
||||
Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)),
|
||||
Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)),
|
||||
Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)),
|
||||
Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables, cx)),
|
||||
Move(place) => stable_mir::mir::Operand::Move(place.stable(tables, cx)),
|
||||
Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables, cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -347,35 +407,48 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
|
||||
type T = stable_mir::mir::ConstOperand;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
stable_mir::mir::ConstOperand {
|
||||
span: self.span.stable(tables),
|
||||
span: self.span.stable(tables, cx),
|
||||
user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
|
||||
const_: self.const_.stable(tables),
|
||||
const_: self.const_.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
|
||||
type T = stable_mir::mir::Place;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
stable_mir::mir::Place {
|
||||
local: self.local.as_usize(),
|
||||
projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
|
||||
projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
|
||||
type T = stable_mir::mir::ProjectionElem;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::ProjectionElem::*;
|
||||
match self {
|
||||
Deref => stable_mir::mir::ProjectionElem::Deref,
|
||||
Field(idx, ty) => {
|
||||
stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables))
|
||||
}
|
||||
Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)),
|
||||
Field(idx, ty) => stable_mir::mir::ProjectionElem::Field(
|
||||
idx.stable(tables, cx),
|
||||
ty.stable(tables, cx),
|
||||
),
|
||||
Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables, cx)),
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
stable_mir::mir::ProjectionElem::ConstantIndex {
|
||||
offset: *offset,
|
||||
|
|
@ -393,9 +466,9 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
|
|||
// via a lookup using the `VariantIdx`. The `Option<Symbol>` argument is therefore
|
||||
// dropped when converting to Stable MIR. A brief justification for this decision can be
|
||||
// found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486
|
||||
Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
|
||||
OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)),
|
||||
Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)),
|
||||
Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables, cx)),
|
||||
OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables, cx)),
|
||||
Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables, cx)),
|
||||
UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
|
||||
}
|
||||
}
|
||||
|
|
@ -404,21 +477,21 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
|
||||
type T = stable_mir::mir::UserTypeProjection;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::Local {
|
||||
type T = stable_mir::mir::Local;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::RetagKind {
|
||||
type T = stable_mir::mir::RetagKind;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::RetagKind;
|
||||
match self {
|
||||
RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry,
|
||||
|
|
@ -431,7 +504,7 @@ impl<'tcx> Stable<'tcx> for mir::RetagKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::UnwindAction {
|
||||
type T = stable_mir::mir::UnwindAction;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::UnwindAction;
|
||||
match self {
|
||||
UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
|
||||
|
|
@ -445,18 +518,22 @@ impl<'tcx> Stable<'tcx> for mir::UnwindAction {
|
|||
impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
|
||||
type T = stable_mir::mir::NonDivergingIntrinsic;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::NonDivergingIntrinsic;
|
||||
use stable_mir::mir::CopyNonOverlapping;
|
||||
match self {
|
||||
NonDivergingIntrinsic::Assume(op) => {
|
||||
stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables))
|
||||
stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables, cx))
|
||||
}
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => {
|
||||
stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
|
||||
src: copy_non_overlapping.src.stable(tables),
|
||||
dst: copy_non_overlapping.dst.stable(tables),
|
||||
count: copy_non_overlapping.count.stable(tables),
|
||||
src: copy_non_overlapping.src.stable(tables, cx),
|
||||
dst: copy_non_overlapping.dst.stable(tables, cx),
|
||||
count: copy_non_overlapping.count.stable(tables, cx),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -465,47 +542,51 @@ impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
|
||||
type T = stable_mir::mir::AssertMessage;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::AssertKind;
|
||||
match self {
|
||||
AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
|
||||
len: len.stable(tables),
|
||||
index: index.stable(tables),
|
||||
len: len.stable(tables, cx),
|
||||
index: index.stable(tables, cx),
|
||||
},
|
||||
AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
|
||||
bin_op.stable(tables),
|
||||
op1.stable(tables),
|
||||
op2.stable(tables),
|
||||
bin_op.stable(tables, cx),
|
||||
op1.stable(tables, cx),
|
||||
op2.stable(tables, cx),
|
||||
),
|
||||
AssertKind::OverflowNeg(op) => {
|
||||
stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables))
|
||||
stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables, cx))
|
||||
}
|
||||
AssertKind::DivisionByZero(op) => {
|
||||
stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables))
|
||||
stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables, cx))
|
||||
}
|
||||
AssertKind::RemainderByZero(op) => {
|
||||
stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables))
|
||||
stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables, cx))
|
||||
}
|
||||
AssertKind::ResumedAfterReturn(coroutine) => {
|
||||
stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables))
|
||||
stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables, cx))
|
||||
}
|
||||
AssertKind::ResumedAfterPanic(coroutine) => {
|
||||
stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
|
||||
stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables, cx))
|
||||
}
|
||||
AssertKind::ResumedAfterDrop(coroutine) => {
|
||||
stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables))
|
||||
stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables, cx))
|
||||
}
|
||||
AssertKind::MisalignedPointerDereference { required, found } => {
|
||||
stable_mir::mir::AssertMessage::MisalignedPointerDereference {
|
||||
required: required.stable(tables),
|
||||
found: found.stable(tables),
|
||||
required: required.stable(tables, cx),
|
||||
found: found.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
AssertKind::NullPointerDereference => {
|
||||
stable_mir::mir::AssertMessage::NullPointerDereference
|
||||
}
|
||||
AssertKind::InvalidEnumConstruction(source) => {
|
||||
stable_mir::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables))
|
||||
stable_mir::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables, cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -513,7 +594,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::BinOp {
|
||||
type T = stable_mir::mir::BinOp;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::BinOp;
|
||||
match self {
|
||||
BinOp::Add => stable_mir::mir::BinOp::Add,
|
||||
|
|
@ -548,7 +629,7 @@ impl<'tcx> Stable<'tcx> for mir::BinOp {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::UnOp {
|
||||
type T = stable_mir::mir::UnOp;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::UnOp;
|
||||
match self {
|
||||
UnOp::Not => stable_mir::mir::UnOp::Not,
|
||||
|
|
@ -560,17 +641,21 @@ impl<'tcx> Stable<'tcx> for mir::UnOp {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
||||
type T = stable_mir::mir::AggregateKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::AggregateKind::Array(ty) => {
|
||||
stable_mir::mir::AggregateKind::Array(ty.stable(tables))
|
||||
stable_mir::mir::AggregateKind::Array(ty.stable(tables, cx))
|
||||
}
|
||||
mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
|
||||
mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
|
||||
stable_mir::mir::AggregateKind::Adt(
|
||||
tables.adt_def(*def_id),
|
||||
var_idx.stable(tables),
|
||||
generic_arg.stable(tables),
|
||||
var_idx.stable(tables, cx),
|
||||
generic_arg.stable(tables, cx),
|
||||
user_ty_index.map(|idx| idx.index()),
|
||||
field_idx.map(|idx| idx.index()),
|
||||
)
|
||||
|
|
@ -578,39 +663,46 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
|||
mir::AggregateKind::Closure(def_id, generic_arg) => {
|
||||
stable_mir::mir::AggregateKind::Closure(
|
||||
tables.closure_def(*def_id),
|
||||
generic_arg.stable(tables),
|
||||
generic_arg.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
mir::AggregateKind::Coroutine(def_id, generic_arg) => {
|
||||
stable_mir::mir::AggregateKind::Coroutine(
|
||||
tables.coroutine_def(*def_id),
|
||||
generic_arg.stable(tables),
|
||||
tables.tcx.coroutine_movability(*def_id).stable(tables),
|
||||
generic_arg.stable(tables, cx),
|
||||
cx.coroutine_movability(*def_id).stable(tables, cx),
|
||||
)
|
||||
}
|
||||
mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
|
||||
stable_mir::mir::AggregateKind::CoroutineClosure(
|
||||
tables.coroutine_closure_def(*def_id),
|
||||
generic_args.stable(tables),
|
||||
generic_args.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
mir::AggregateKind::RawPtr(ty, mutability) => {
|
||||
stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
|
||||
}
|
||||
mir::AggregateKind::RawPtr(ty, mutability) => stable_mir::mir::AggregateKind::RawPtr(
|
||||
ty.stable(tables, cx),
|
||||
mutability.stable(tables, cx),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
|
||||
type T = stable_mir::mir::InlineAsmOperand;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::InlineAsmOperand;
|
||||
|
||||
let (in_value, out_place) = match self {
|
||||
InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None),
|
||||
InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))),
|
||||
InlineAsmOperand::In { value, .. } => (Some(value.stable(tables, cx)), None),
|
||||
InlineAsmOperand::Out { place, .. } => {
|
||||
(None, place.map(|place| place.stable(tables, cx)))
|
||||
}
|
||||
InlineAsmOperand::InOut { in_value, out_place, .. } => {
|
||||
(Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables)))
|
||||
(Some(in_value.stable(tables, cx)), out_place.map(|place| place.stable(tables, cx)))
|
||||
}
|
||||
InlineAsmOperand::Const { .. }
|
||||
| InlineAsmOperand::SymFn { .. }
|
||||
|
|
@ -624,22 +716,33 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
|
||||
type T = stable_mir::mir::Terminator;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use stable_mir::mir::Terminator;
|
||||
Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
|
||||
Terminator {
|
||||
kind: self.kind.stable(tables, cx),
|
||||
span: self.source_info.span.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
||||
type T = stable_mir::mir::TerminatorKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use stable_mir::mir::TerminatorKind;
|
||||
match self {
|
||||
mir::TerminatorKind::Goto { target } => {
|
||||
TerminatorKind::Goto { target: target.as_usize() }
|
||||
}
|
||||
mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
|
||||
discr: discr.stable(tables),
|
||||
discr: discr.stable(tables, cx),
|
||||
targets: {
|
||||
let branches = targets.iter().map(|(val, target)| (val, target.as_usize()));
|
||||
stable_mir::mir::SwitchTargets::new(
|
||||
|
|
@ -660,9 +763,9 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
|||
drop: _,
|
||||
async_fut: _,
|
||||
} => TerminatorKind::Drop {
|
||||
place: place.stable(tables),
|
||||
place: place.stable(tables, cx),
|
||||
target: target.as_usize(),
|
||||
unwind: unwind.stable(tables),
|
||||
unwind: unwind.stable(tables, cx),
|
||||
},
|
||||
mir::TerminatorKind::Call {
|
||||
func,
|
||||
|
|
@ -673,20 +776,20 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
|||
call_source: _,
|
||||
fn_span: _,
|
||||
} => TerminatorKind::Call {
|
||||
func: func.stable(tables),
|
||||
args: args.iter().map(|arg| arg.node.stable(tables)).collect(),
|
||||
destination: destination.stable(tables),
|
||||
func: func.stable(tables, cx),
|
||||
args: args.iter().map(|arg| arg.node.stable(tables, cx)).collect(),
|
||||
destination: destination.stable(tables, cx),
|
||||
target: target.map(|t| t.as_usize()),
|
||||
unwind: unwind.stable(tables),
|
||||
unwind: unwind.stable(tables, cx),
|
||||
},
|
||||
mir::TerminatorKind::TailCall { func: _, args: _, fn_span: _ } => todo!(),
|
||||
mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
|
||||
TerminatorKind::Assert {
|
||||
cond: cond.stable(tables),
|
||||
cond: cond.stable(tables, cx),
|
||||
expected: *expected,
|
||||
msg: msg.stable(tables),
|
||||
msg: msg.stable(tables, cx),
|
||||
target: target.as_usize(),
|
||||
unwind: unwind.stable(tables),
|
||||
unwind: unwind.stable(tables, cx),
|
||||
}
|
||||
}
|
||||
mir::TerminatorKind::InlineAsm {
|
||||
|
|
@ -699,12 +802,12 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
|||
unwind,
|
||||
} => TerminatorKind::InlineAsm {
|
||||
template: format!("{template:?}"),
|
||||
operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
|
||||
operands: operands.iter().map(|operand| operand.stable(tables, cx)).collect(),
|
||||
options: format!("{options:?}"),
|
||||
line_spans: format!("{line_spans:?}"),
|
||||
// FIXME: Figure out how to do labels in SMIR
|
||||
destination: targets.first().map(|d| d.as_usize()),
|
||||
unwind: unwind.stable(tables),
|
||||
unwind: unwind.stable(tables, cx),
|
||||
},
|
||||
mir::TerminatorKind::Yield { .. }
|
||||
| mir::TerminatorKind::CoroutineDrop
|
||||
|
|
@ -717,22 +820,40 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
|
||||
type T = Allocation;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
self.inner().stable(tables)
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.inner().stable(tables, cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
|
||||
type T = stable_mir::ty::Allocation;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
alloc::allocation_filter(self, alloc_range(rustc_abi::Size::ZERO, self.size()), tables)
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_smir::context::SmirAllocRange;
|
||||
alloc::allocation_filter(
|
||||
self,
|
||||
cx.alloc_range(rustc_abi::Size::ZERO, self.size()),
|
||||
tables,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
|
||||
type T = stable_mir::mir::alloc::AllocId;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
_: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.create_alloc_id(*self)
|
||||
}
|
||||
}
|
||||
|
|
@ -740,19 +861,25 @@ impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
|
|||
impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
|
||||
type T = GlobalAlloc;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::interpret::GlobalAlloc::Function { instance, .. } => {
|
||||
GlobalAlloc::Function(instance.stable(tables))
|
||||
GlobalAlloc::Function(instance.stable(tables, cx))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::VTable(ty, dyn_ty) => {
|
||||
// FIXME: Should we record the whole vtable?
|
||||
GlobalAlloc::VTable(ty.stable(tables), dyn_ty.principal().stable(tables))
|
||||
GlobalAlloc::VTable(ty.stable(tables, cx), dyn_ty.principal().stable(tables, cx))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::Static(def) => {
|
||||
GlobalAlloc::Static(tables.static_def(*def))
|
||||
}
|
||||
mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
|
||||
mir::interpret::GlobalAlloc::Memory(alloc) => {
|
||||
GlobalAlloc::Memory(alloc.stable(tables, cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -760,33 +887,37 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
||||
type T = stable_mir::ty::MirConst;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap());
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let id = tables.intern_mir_const(cx.lift(*self).unwrap());
|
||||
match *self {
|
||||
mir::Const::Ty(ty, c) => MirConst::new(
|
||||
stable_mir::ty::ConstantKind::Ty(c.stable(tables)),
|
||||
ty.stable(tables),
|
||||
stable_mir::ty::ConstantKind::Ty(c.stable(tables, cx)),
|
||||
ty.stable(tables, cx),
|
||||
id,
|
||||
),
|
||||
mir::Const::Unevaluated(unev_const, ty) => {
|
||||
let kind =
|
||||
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
|
||||
def: tables.const_def(unev_const.def),
|
||||
args: unev_const.args.stable(tables),
|
||||
args: unev_const.args.stable(tables, cx),
|
||||
promoted: unev_const.promoted.map(|u| u.as_u32()),
|
||||
});
|
||||
let ty = ty.stable(tables);
|
||||
let ty = ty.stable(tables, cx);
|
||||
MirConst::new(kind, ty, id)
|
||||
}
|
||||
mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
|
||||
let ty = ty.stable(tables);
|
||||
let ty = ty.stable(tables, cx);
|
||||
MirConst::new(ConstantKind::ZeroSized, ty, id)
|
||||
}
|
||||
mir::Const::Val(val, ty) => {
|
||||
let ty = tables.tcx.lift(ty).unwrap();
|
||||
let val = tables.tcx.lift(val).unwrap();
|
||||
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
|
||||
let ty = ty.stable(tables);
|
||||
let ty = cx.lift(ty).unwrap();
|
||||
let val = cx.lift(val).unwrap();
|
||||
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables, cx));
|
||||
let ty = ty.stable(tables, cx);
|
||||
MirConst::new(kind, ty, id)
|
||||
}
|
||||
}
|
||||
|
|
@ -796,7 +927,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
|
||||
type T = Error;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
Error::new(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
|
@ -804,10 +935,14 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
|
|||
impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
|
||||
type T = stable_mir::mir::mono::MonoItem;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use stable_mir::mir::mono::MonoItem as StableMonoItem;
|
||||
match self {
|
||||
MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)),
|
||||
MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables, cx)),
|
||||
MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
|
||||
MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
|
||||
}
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
//! Conversion of internal Rust compiler items to stable ones.
|
||||
|
||||
use rustc_abi::FieldIdx;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use stable_mir::compiler_interface::BridgeTys;
|
||||
|
||||
use crate::rustc_smir::{Stable, Tables};
|
||||
use crate::stable_mir;
|
||||
use super::Stable;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
mod abi;
|
||||
mod error;
|
||||
mod mir;
|
||||
mod ty;
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
||||
type T = stable_mir::mir::Safety;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_hir::Safety::Unsafe => stable_mir::mir::Safety::Unsafe,
|
||||
rustc_hir::Safety::Safe => stable_mir::mir::Safety::Safe,
|
||||
|
|
@ -22,14 +24,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for FieldIdx {
|
||||
type T = usize;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
|
||||
type T = stable_mir::mir::CoroutineSource;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_hir::CoroutineSource;
|
||||
match self {
|
||||
CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block,
|
||||
|
|
@ -41,28 +43,32 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
||||
type T = stable_mir::mir::CoroutineKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_hir::{CoroutineDesugaring, CoroutineKind};
|
||||
match *self {
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Async, source) => {
|
||||
stable_mir::mir::CoroutineKind::Desugared(
|
||||
stable_mir::mir::CoroutineDesugaring::Async,
|
||||
source.stable(tables),
|
||||
source.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, source) => {
|
||||
stable_mir::mir::CoroutineKind::Desugared(
|
||||
stable_mir::mir::CoroutineDesugaring::Gen,
|
||||
source.stable(tables),
|
||||
source.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
CoroutineKind::Coroutine(movability) => {
|
||||
stable_mir::mir::CoroutineKind::Coroutine(movability.stable(tables))
|
||||
stable_mir::mir::CoroutineKind::Coroutine(movability.stable(tables, cx))
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, source) => {
|
||||
stable_mir::mir::CoroutineKind::Desugared(
|
||||
stable_mir::mir::CoroutineDesugaring::AsyncGen,
|
||||
source.stable(tables),
|
||||
source.stable(tables, cx),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +78,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
|||
impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
|
||||
type T = stable_mir::Symbol;
|
||||
|
||||
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +86,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
|
|||
impl<'tcx> Stable<'tcx> for rustc_span::Span {
|
||||
type T = stable_mir::ty::Span;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
_: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.create_span(*self)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
210
compiler/rustc_smir/src/stable_mir/unstable/mod.rs
Normal file
210
compiler/rustc_smir/src/stable_mir/unstable/mod.rs
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
//! Module that collects the things that have no stability guarantees.
|
||||
//!
|
||||
//! We want to keep StableMIR 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.
|
||||
|
||||
use std::marker::PointeeSized;
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::ty::{List, Ty, TyCtxt};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::{
|
||||
SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirTraitRef,
|
||||
};
|
||||
use stable_mir::{CtorKind, ItemKind};
|
||||
|
||||
use super::compiler_interface::BridgeTys;
|
||||
use crate::{rustc_smir, stable_mir};
|
||||
|
||||
pub(crate) mod convert;
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
def_id: rustc_span::def_id::DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
term: ty::Term<'tcx>,
|
||||
) -> ty::ExistentialProjection<'tcx> {
|
||||
ty::ExistentialProjection::new_from_args(self.tcx(), def_id, args, term)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> ty::ExistentialTraitRef<'tcx> {
|
||||
ty::ExistentialTraitRef::new_from_args(self.tcx(), trait_def_id, args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirTraitRef<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
ty::TraitRef::new_from_args(self.tcx(), trait_def_id, args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> {
|
||||
fn tcx(self) -> TyCtxt<'tcx> {
|
||||
self
|
||||
}
|
||||
|
||||
fn lift<T: ty::Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
|
||||
TyCtxt::lift(self, value)
|
||||
}
|
||||
|
||||
fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
|
||||
{
|
||||
TyCtxt::mk_args_from_iter(self, iter)
|
||||
}
|
||||
|
||||
fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> {
|
||||
TyCtxt::mk_pat(self, v)
|
||||
}
|
||||
|
||||
fn mk_poly_existential_predicates(
|
||||
self,
|
||||
eps: &[ty::PolyExistentialPredicate<'tcx>],
|
||||
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
|
||||
TyCtxt::mk_poly_existential_predicates(self, eps)
|
||||
}
|
||||
|
||||
fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
|
||||
TyCtxt::mk_type_list(self, v)
|
||||
}
|
||||
|
||||
fn lifetimes_re_erased(self) -> ty::Region<'tcx> {
|
||||
self.lifetimes.re_erased
|
||||
}
|
||||
|
||||
fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
|
||||
{
|
||||
TyCtxt::mk_bound_variable_kinds_from_iter(self, iter)
|
||||
}
|
||||
|
||||
fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>> {
|
||||
TyCtxt::mk_place_elems(self, v)
|
||||
}
|
||||
|
||||
fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx> {
|
||||
self.adt_def(def_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 [`crate::rustc_smir::context::SmirCtxt`].
|
||||
pub trait InternalCx<'tcx>: Copy + Clone {
|
||||
fn tcx(self) -> TyCtxt<'tcx>;
|
||||
|
||||
fn lift<T: ty::Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted>;
|
||||
|
||||
fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>;
|
||||
|
||||
fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx>;
|
||||
|
||||
fn mk_poly_existential_predicates(
|
||||
self,
|
||||
eps: &[ty::PolyExistentialPredicate<'tcx>],
|
||||
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>>;
|
||||
|
||||
fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>>;
|
||||
|
||||
fn lifetimes_re_erased(self) -> ty::Region<'tcx>;
|
||||
|
||||
fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>;
|
||||
|
||||
fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>>;
|
||||
|
||||
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.
|
||||
///
|
||||
/// 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.
|
||||
#[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.
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T;
|
||||
}
|
||||
|
||||
/// Trait used to translate a stable 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.
|
||||
#[doc(hidden)]
|
||||
pub trait RustcInternal {
|
||||
type T<'tcx>;
|
||||
fn internal<'tcx>(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx>;
|
||||
}
|
||||
|
||||
pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
|
||||
match kind {
|
||||
DefKind::Mod
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::TyParam
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Macro(_)
|
||||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::GlobalAsm => {
|
||||
unreachable!("Not a valid item kind: {kind:?}");
|
||||
}
|
||||
DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
|
||||
ItemKind::Fn
|
||||
}
|
||||
DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
|
||||
ItemKind::Const
|
||||
}
|
||||
DefKind::Static { .. } => ItemKind::Static,
|
||||
DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
|
||||
DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
|
||||
}
|
||||
}
|
||||
|
|
@ -1623,7 +1623,6 @@ symbols! {
|
|||
pointee_sized,
|
||||
pointee_trait,
|
||||
pointer,
|
||||
pointer_like,
|
||||
poll,
|
||||
poll_next,
|
||||
position,
|
||||
|
|
|
|||
|
|
@ -21,19 +21,9 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
|
|||
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) =
|
||||
key.value.predicate.kind().skip_binder()
|
||||
&& term.is_trivially_wf(tcx)
|
||||
{
|
||||
match term.as_type()?.kind() {
|
||||
ty::Param(_)
|
||||
| ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Float(_)
|
||||
| ty::Str
|
||||
| ty::Uint(_) => {
|
||||
return Some(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return Some(());
|
||||
}
|
||||
|
||||
None
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ use rustc_hir::lang_items::LangItem;
|
|||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate,
|
||||
};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::def_id::DefId;
|
||||
use thin_vec::thin_vec;
|
||||
|
|
@ -1147,38 +1145,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
|
||||
));
|
||||
|
||||
// Require that all AFIT will return something that can be coerced into `dyn*`
|
||||
// -- a shim will be responsible for doing the actual coercion to `dyn*`.
|
||||
if let Some(principal) = data.principal() {
|
||||
for supertrait in
|
||||
elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
|
||||
{
|
||||
if tcx.is_trait_alias(supertrait.def_id()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
|
||||
if !tcx.is_impl_trait_in_trait(assoc_item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// RPITITs with `Self: Sized` don't need to be checked.
|
||||
if tcx.generics_require_sized_self(assoc_item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pointer_like_goal = pointer_like_goal_for_rpitit(
|
||||
tcx,
|
||||
supertrait,
|
||||
assoc_item,
|
||||
&obligation.cause,
|
||||
);
|
||||
|
||||
nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImplSource::Builtin(BuiltinImplSource::Misc, nested)
|
||||
}
|
||||
|
||||
|
|
@ -1344,46 +1310,3 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures)
|
||||
/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be
|
||||
/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent
|
||||
/// trait to be coercible to `dyn Trait`.
|
||||
///
|
||||
/// We do this given a supertrait's substitutions, and then augment the substitutions
|
||||
/// with bound variables to compute the goal universally. Given that `PointerLike` has
|
||||
/// no region requirements (at least for the built-in pointer types), this shouldn't
|
||||
/// *really* matter, but it is the best choice for soundness.
|
||||
fn pointer_like_goal_for_rpitit<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
supertrait: ty::PolyTraitRef<'tcx>,
|
||||
rpitit_item: DefId,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
) -> ty::PolyTraitRef<'tcx> {
|
||||
let mut bound_vars = supertrait.bound_vars().to_vec();
|
||||
|
||||
let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
|
||||
ty::GenericParamDefKind::Lifetime => {
|
||||
let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
|
||||
bound_vars.push(ty::BoundVariableKind::Region(kind));
|
||||
ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
|
||||
)
|
||||
.into()
|
||||
}
|
||||
ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
});
|
||||
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::PointerLike, cause.span),
|
||||
[Ty::new_projection_from_args(tcx, rpitit_item, args)],
|
||||
),
|
||||
tcx.mk_bound_variable_kinds(&bound_vars),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,16 +368,17 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
|||
// Proving `Sized`/`MetaSized`, very often on "obviously sized" types like
|
||||
// `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to
|
||||
// canonicalize and all that for such cases.
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) =
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
|
||||
predicate.kind().skip_binder()
|
||||
&& trait_pred.polarity == ty::PredicatePolarity::Positive
|
||||
{
|
||||
let sizedness = match tcx.as_lang_item(trait_ref.def_id()) {
|
||||
let sizedness = match tcx.as_lang_item(trait_pred.def_id()) {
|
||||
Some(LangItem::Sized) => SizedTraitKind::Sized,
|
||||
Some(LangItem::MetaSized) => SizedTraitKind::MetaSized,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) {
|
||||
if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) {
|
||||
debug!("fast path -- trivial sizedness");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::traits::CodegenObligationError;
|
||||
use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Upcast};
|
||||
use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext,
|
||||
SelectionError, sizedness_fast_path,
|
||||
SelectionError,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
|
|
@ -34,13 +34,6 @@ pub(crate) fn codegen_select_candidate<'tcx>(
|
|||
let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
|
||||
if sizedness_fast_path(tcx, trait_ref.upcast(tcx)) {
|
||||
return Ok(&*tcx.arena.alloc(ImplSource::Builtin(
|
||||
ty::solve::BuiltinImplSource::Trivial,
|
||||
Default::default(),
|
||||
)));
|
||||
}
|
||||
|
||||
let obligation_cause = ObligationCause::dummy();
|
||||
let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref);
|
||||
|
||||
|
|
|
|||
|
|
@ -429,10 +429,10 @@ pub mod __alloc_error_handler {
|
|||
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
|
||||
// Its value depends on the -Zoom={panic,abort} compiler option.
|
||||
#[rustc_std_internal_symbol]
|
||||
static __rust_alloc_error_handler_should_panic: u8;
|
||||
fn __rust_alloc_error_handler_should_panic_v2() -> u8;
|
||||
}
|
||||
|
||||
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
|
||||
if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
|
||||
panic!("memory allocation of {size} bytes failed")
|
||||
} else {
|
||||
core::panicking::panic_nounwind_fmt(
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ use core::error::{self, Error};
|
|||
use core::fmt;
|
||||
use core::future::Future;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::marker::{PointerLike, Tuple, Unsize};
|
||||
use core::marker::{Tuple, Unsize};
|
||||
use core::mem::{self, SizedTypeProperties};
|
||||
use core::ops::{
|
||||
AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut,
|
||||
|
|
@ -2132,6 +2132,3 @@ impl<E: Error> Error for Box<E> {
|
|||
Error::provide(&**self, request);
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T> PointerLike for Box<T> {}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,6 @@
|
|||
#![feature(panic_internals)]
|
||||
#![feature(pattern)]
|
||||
#![feature(pin_coerce_unsized_trait)]
|
||||
#![feature(pointer_like_trait)]
|
||||
#![feature(ptr_alignment_type)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(ptr_metadata)]
|
||||
|
|
|
|||
|
|
@ -61,4 +61,71 @@ impl bool {
|
|||
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
||||
if self { Some(f()) } else { None }
|
||||
}
|
||||
|
||||
/// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html),
|
||||
/// or `Err(err)` otherwise.
|
||||
///
|
||||
/// Arguments passed to `ok_or` are eagerly evaluated; if you are
|
||||
/// passing the result of a function call, it is recommended to use
|
||||
/// [`ok_or_else`], which is lazily evaluated.
|
||||
///
|
||||
/// [`ok_or_else`]: bool::ok_or_else
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_result)]
|
||||
///
|
||||
/// assert_eq!(false.ok_or(0), Err(0));
|
||||
/// assert_eq!(true.ok_or(0), Ok(()));
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_result)]
|
||||
///
|
||||
/// let mut a = 0;
|
||||
/// let mut function_with_side_effects = || { a += 1; };
|
||||
///
|
||||
/// assert!(true.ok_or(function_with_side_effects()).is_ok());
|
||||
/// assert!(false.ok_or(function_with_side_effects()).is_err());
|
||||
///
|
||||
/// // `a` is incremented twice because the value passed to `ok_or` is
|
||||
/// // evaluated eagerly.
|
||||
/// assert_eq!(a, 2);
|
||||
/// ```
|
||||
#[unstable(feature = "bool_to_result", issue = "142748")]
|
||||
#[inline]
|
||||
pub fn ok_or<E>(self, err: E) -> Result<(), E> {
|
||||
if self { Ok(()) } else { Err(err) }
|
||||
}
|
||||
|
||||
/// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html),
|
||||
/// or `Err(f())` otherwise.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_result)]
|
||||
///
|
||||
/// assert_eq!(false.ok_or_else(|| 0), Err(0));
|
||||
/// assert_eq!(true.ok_or_else(|| 0), Ok(()));
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_result)]
|
||||
///
|
||||
/// let mut a = 0;
|
||||
///
|
||||
/// assert!(true.ok_or_else(|| { a += 1; }).is_ok());
|
||||
/// assert!(false.ok_or_else(|| { a += 1; }).is_err());
|
||||
///
|
||||
/// // `a` is incremented once because the closure is evaluated lazily by
|
||||
/// // `ok_or_else`.
|
||||
/// assert_eq!(a, 1);
|
||||
/// ```
|
||||
#[unstable(feature = "bool_to_result", issue = "142748")]
|
||||
#[inline]
|
||||
pub fn ok_or_else<E, F: FnOnce() -> E>(self, f: F) -> Result<(), E> {
|
||||
if self { Ok(()) } else { Err(f()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@
|
|||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::fmt::{self, Debug, Display};
|
||||
use crate::marker::{PhantomData, PointerLike, Unsize};
|
||||
use crate::marker::{PhantomData, Unsize};
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
|
||||
use crate::panic::const_panic;
|
||||
|
|
@ -669,9 +669,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
|
|||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for Cell<T> {}
|
||||
|
||||
impl<T> Cell<[T]> {
|
||||
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
|
||||
///
|
||||
|
|
@ -2361,9 +2358,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
|
|||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for UnsafeCell<T> {}
|
||||
|
||||
/// [`UnsafeCell`], but [`Sync`].
|
||||
///
|
||||
/// This is just an `UnsafeCell`, except it implements `Sync`
|
||||
|
|
@ -2470,9 +2464,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
|
|||
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for SyncUnsafeCell<T> {}
|
||||
|
||||
#[allow(unused)]
|
||||
fn assert_coerce_unsized(
|
||||
a: UnsafeCell<&i32>,
|
||||
|
|
|
|||
|
|
@ -1449,7 +1449,6 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
|||
/// check `==` and `<` separately to do rather than needing to calculate
|
||||
/// (then optimize out) the three-way `Ordering` result.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
// Added to improve the behaviour of tuples; not necessarily stabilization-track.
|
||||
#[unstable(feature = "partial_ord_chaining_methods", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
|
|
@ -1459,7 +1458,6 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
|||
|
||||
/// Same as `__chaining_lt`, but for `<=` instead of `<`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "partial_ord_chaining_methods", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
fn __chaining_le(&self, other: &Rhs) -> ControlFlow<bool> {
|
||||
|
|
@ -1468,7 +1466,6 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
|||
|
||||
/// Same as `__chaining_lt`, but for `>` instead of `<`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "partial_ord_chaining_methods", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
fn __chaining_gt(&self, other: &Rhs) -> ControlFlow<bool> {
|
||||
|
|
@ -1477,7 +1474,6 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
|||
|
||||
/// Same as `__chaining_lt`, but for `>=` instead of `<`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "partial_ord_chaining_methods", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
fn __chaining_ge(&self, other: &Rhs) -> ControlFlow<bool> {
|
||||
|
|
|
|||
|
|
@ -1066,37 +1066,6 @@ pub trait Destruct {}
|
|||
#[rustc_do_not_implement_via_object]
|
||||
pub trait Tuple {}
|
||||
|
||||
/// A marker for pointer-like types.
|
||||
///
|
||||
/// This trait can only be implemented for types that are certain to have
|
||||
/// the same size and alignment as a [`usize`] or [`*const ()`](pointer).
|
||||
/// To ensure this, there are special requirements on implementations
|
||||
/// of `PointerLike` (other than the already-provided implementations
|
||||
/// for built-in types):
|
||||
///
|
||||
/// * The type must have `#[repr(transparent)]`.
|
||||
/// * The type’s sole non-zero-sized field must itself implement `PointerLike`.
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
#[lang = "pointer_like"]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` needs to have the same ABI as a pointer",
|
||||
label = "`{Self}` needs to be a pointer-like type"
|
||||
)]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
pub trait PointerLike {}
|
||||
|
||||
marker_impls! {
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
PointerLike for
|
||||
isize,
|
||||
usize,
|
||||
{T} &T,
|
||||
{T} &mut T,
|
||||
{T} *const T,
|
||||
{T} *mut T,
|
||||
{T: PointerLike} crate::pin::Pin<T>,
|
||||
}
|
||||
|
||||
/// A marker for types which can be used as types of `const` generic parameters.
|
||||
///
|
||||
/// These types must have a proper equivalence relation (`Eq`) and it must be automatically
|
||||
|
|
|
|||
|
|
@ -943,7 +943,7 @@ impl f64 {
|
|||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f64::max`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```ignore-arm-unknown-linux-gnueabihf,ignore-i586 (see https://github.com/rust-lang/rust/issues/141087)
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
|
|
@ -970,7 +970,7 @@ impl f64 {
|
|||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f64::min`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```ignore-arm-unknown-linux-gnueabihf,ignore-i586 (see https://github.com/rust-lang/rust/issues/141087)
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
|
|
|
|||
|
|
@ -2572,7 +2572,7 @@ macro_rules! uint_impl {
|
|||
if size_of::<Self>() == 1 {
|
||||
// Trick LLVM into generating the psadbw instruction when SSE2
|
||||
// is available and this function is autovectorized for u8's.
|
||||
(self as i32).wrapping_sub(other as i32).abs() as Self
|
||||
(self as i32).wrapping_sub(other as i32).unsigned_abs() as Self
|
||||
} else {
|
||||
if self < other {
|
||||
other - self
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::cell::UnsafeCell;
|
||||
use crate::marker::{PointerLike, Unpin};
|
||||
use crate::marker::Unpin;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::pin::Pin;
|
||||
use crate::{fmt, ptr};
|
||||
|
|
@ -178,8 +178,4 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafePinned<U>> for UnsafePinned<T>
|
|||
// #[unstable(feature = "unsafe_pinned", issue = "125735")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafePinned<U>> for UnsafePinned<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
// #[unstable(feature = "unsafe_pinned", issue = "125735")]
|
||||
impl<T: PointerLike> PointerLike for UnsafePinned<T> {}
|
||||
|
||||
// FIXME(unsafe_pinned): impl PinCoerceUnsized for UnsafePinned<T>?
|
||||
|
|
|
|||
|
|
@ -1628,9 +1628,6 @@ impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T
|
|||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
unsafe impl<T: PointeeSized> PinCoerceUnsized for NonNull<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T> core::marker::PointerLike for NonNull<T> {}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: PointeeSized> fmt::Debug for NonNull<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
|||
|
|
@ -105,3 +105,11 @@ fn test_bool_to_option() {
|
|||
assert_eq!(D, Some(0));
|
||||
*/
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_to_result() {
|
||||
assert_eq!(false.ok_or(0), Err(0));
|
||||
assert_eq!(true.ok_or(0), Ok(()));
|
||||
assert_eq!(false.ok_or_else(|| 0), Err(0));
|
||||
assert_eq!(true.ok_or_else(|| 0), Ok(()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#![feature(async_iter_from_iter)]
|
||||
#![feature(async_iterator)]
|
||||
#![feature(bigint_helper_methods)]
|
||||
#![feature(bool_to_result)]
|
||||
#![feature(bstr)]
|
||||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(char_max_len)]
|
||||
|
|
|
|||
|
|
@ -349,10 +349,10 @@ fn default_alloc_error_hook(layout: Layout) {
|
|||
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
|
||||
// Its value depends on the -Zoom={panic,abort} compiler option.
|
||||
#[rustc_std_internal_symbol]
|
||||
static __rust_alloc_error_handler_should_panic: u8;
|
||||
fn __rust_alloc_error_handler_should_panic_v2() -> u8;
|
||||
}
|
||||
|
||||
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
|
||||
if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
|
||||
panic!("memory allocation of {} bytes failed", layout.size());
|
||||
} else {
|
||||
// This is the default path taken on OOM, and the only path taken on stable with std.
|
||||
|
|
|
|||
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