Auto merge of #150041 - Zalathar:rollup-sa5nez6, r=Zalathar
Rollup of 13 pull requests Successful merges: - rust-lang/rust#148756 (Warn on codegen attributes on required trait methods) - rust-lang/rust#148790 (Add new Tier-3 target: riscv64im-unknown-none-elf) - rust-lang/rust#149271 (feat: dlopen Enzyme) - rust-lang/rust#149459 (std: sys: fs: uefi: Implement set_times and set_perm) - rust-lang/rust#149771 (bootstrap readme: make easy to read when editor wrapping is not enabled) - rust-lang/rust#149856 (Provide an extended framework for type visit, for use in rust-analyzer) - rust-lang/rust#149950 (Simplify how inline asm handles `MaybeUninit`) - rust-lang/rust#150014 (Metadata loader cleanups) - rust-lang/rust#150021 (document that mpmc channels deliver an item to (at most) one receiver) - rust-lang/rust#150029 (Update books) - rust-lang/rust#150031 (assert impossible branch is impossible) - rust-lang/rust#150034 (do not add `I-prioritize` when `F-*` labels are present) - rust-lang/rust#150036 (Use the embeddable filename for coverage artifacts) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6e7dd2cd99
64 changed files with 1295 additions and 496 deletions
|
|
@ -3613,6 +3613,7 @@ dependencies = [
|
|||
"gimli 0.31.1",
|
||||
"itertools",
|
||||
"libc",
|
||||
"libloading 0.9.0",
|
||||
"measureme",
|
||||
"object 0.37.3",
|
||||
"rustc-demangle",
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
|
|||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ColdParser {
|
|||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::ForeignFn),
|
||||
Allow(Target::Closure),
|
||||
|
|
@ -343,7 +342,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for TrackCallerParser {
|
|||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })), // `#[track_caller]` is inherited from trait methods
|
||||
Allow(Target::ForeignFn),
|
||||
Allow(Target::Closure),
|
||||
Warn(Target::MacroDef),
|
||||
|
|
|
|||
|
|
@ -469,7 +469,6 @@ impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
|
|||
Allow(Target::Static),
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
]);
|
||||
|
|
@ -587,12 +586,12 @@ impl<S: Stage> SingleAttributeParser<S> for LinkageParser {
|
|||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Static),
|
||||
Allow(Target::ForeignStatic),
|
||||
Allow(Target::ForeignFn),
|
||||
Warn(Target::Method(MethodKind::Trait { body: false })), // Not inherited
|
||||
]);
|
||||
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: [
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ impl<S: Stage> AttributeParser<S> for AlignParser {
|
|||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })), // `#[align]` is inherited from trait methods
|
||||
Allow(Target::ForeignFn),
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -857,19 +857,9 @@ fn call_inline_asm<'tcx>(
|
|||
|
||||
fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
|
||||
match ty.kind() {
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/df44a57fd29fca899ce473f85ed64efd0708dd7c/compiler/rustc_hir_typeck/src/inline_asm.rs#L180-L183
|
||||
ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::ONE].ty(fx.tcx, args);
|
||||
let ty::Adt(ty, args) = ty.kind() else {
|
||||
unreachable!("expected first field of `MaybeUninit` to be an ADT")
|
||||
};
|
||||
assert!(
|
||||
ty.is_manually_drop(),
|
||||
"expected first field of `MaybeUninit` to be `ManuallyDrop`"
|
||||
);
|
||||
let fields = &ty.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::ZERO].ty(fx.tcx, args);
|
||||
let ty = args.type_at(0);
|
||||
fx.clif_type(ty)
|
||||
}
|
||||
_ => fx.clif_type(ty),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ bitflags = "2.4.1"
|
|||
gimli = "0.31"
|
||||
itertools = "0.12"
|
||||
libc = "0.2"
|
||||
libloading = { version = "0.9.0", optional = true }
|
||||
measureme = "12.0.1"
|
||||
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
|
||||
rustc-demangle = "0.1.21"
|
||||
|
|
@ -46,7 +47,7 @@ tracing = "0.1"
|
|||
[features]
|
||||
# tidy-alphabetical-start
|
||||
check_only = ["rustc_llvm/check_only"]
|
||||
llvm_enzyme = []
|
||||
llvm_enzyme = ["dep:libloading"]
|
||||
llvm_offload = []
|
||||
# tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -528,31 +528,34 @@ fn thin_lto(
|
|||
}
|
||||
}
|
||||
|
||||
fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
|
||||
#[cfg(feature = "llvm_enzyme")]
|
||||
pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
|
||||
let mut enzyme = llvm::EnzymeWrapper::get_instance();
|
||||
|
||||
for val in ad {
|
||||
// We intentionally don't use a wildcard, to not forget handling anything new.
|
||||
match val {
|
||||
config::AutoDiff::PrintPerf => {
|
||||
llvm::set_print_perf(true);
|
||||
enzyme.set_print_perf(true);
|
||||
}
|
||||
config::AutoDiff::PrintAA => {
|
||||
llvm::set_print_activity(true);
|
||||
enzyme.set_print_activity(true);
|
||||
}
|
||||
config::AutoDiff::PrintTA => {
|
||||
llvm::set_print_type(true);
|
||||
enzyme.set_print_type(true);
|
||||
}
|
||||
config::AutoDiff::PrintTAFn(fun) => {
|
||||
llvm::set_print_type(true); // Enable general type printing
|
||||
llvm::set_print_type_fun(&fun); // Set specific function to analyze
|
||||
enzyme.set_print_type(true); // Enable general type printing
|
||||
enzyme.set_print_type_fun(&fun); // Set specific function to analyze
|
||||
}
|
||||
config::AutoDiff::Inline => {
|
||||
llvm::set_inline(true);
|
||||
enzyme.set_inline(true);
|
||||
}
|
||||
config::AutoDiff::LooseTypes => {
|
||||
llvm::set_loose_types(true);
|
||||
enzyme.set_loose_types(true);
|
||||
}
|
||||
config::AutoDiff::PrintSteps => {
|
||||
llvm::set_print(true);
|
||||
enzyme.set_print(true);
|
||||
}
|
||||
// We handle this in the PassWrapper.cpp
|
||||
config::AutoDiff::PrintPasses => {}
|
||||
|
|
@ -571,9 +574,9 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
|
|||
}
|
||||
}
|
||||
// This helps with handling enums for now.
|
||||
llvm::set_strict_aliasing(false);
|
||||
enzyme.set_strict_aliasing(false);
|
||||
// FIXME(ZuseZ4): Test this, since it was added a long time ago.
|
||||
llvm::set_rust_rules(true);
|
||||
enzyme.set_rust_rules(true);
|
||||
}
|
||||
|
||||
pub(crate) fn run_pass_manager(
|
||||
|
|
@ -607,10 +610,6 @@ pub(crate) fn run_pass_manager(
|
|||
if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }
|
||||
};
|
||||
|
||||
if enable_ad {
|
||||
enable_autodiff_settings(&config.autodiff);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -730,6 +730,13 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
|
||||
let llvm_plugins = config.llvm_plugins.join(",");
|
||||
|
||||
let enzyme_fn = if consider_ad {
|
||||
let wrapper = llvm::EnzymeWrapper::get_instance();
|
||||
wrapper.registerEnzymeAndPassPipeline
|
||||
} else {
|
||||
std::ptr::null()
|
||||
};
|
||||
|
||||
let result = unsafe {
|
||||
llvm::LLVMRustOptimize(
|
||||
module.module_llvm.llmod(),
|
||||
|
|
@ -749,7 +756,7 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
vectorize_loop,
|
||||
config.no_builtins,
|
||||
config.emit_lifetime_markers,
|
||||
run_enzyme,
|
||||
enzyme_fn,
|
||||
print_before_enzyme,
|
||||
print_after_enzyme,
|
||||
print_passes,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{RemapPathScopeComponents, SourceFile, StableSourceFileId};
|
||||
use rustc_span::{FileName, RemapPathScopeComponents, SourceFile, StableSourceFileId};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::common::CodegenCx;
|
||||
|
|
@ -125,7 +125,19 @@ impl GlobalFileTable {
|
|||
|
||||
for file in all_files {
|
||||
raw_file_table.entry(file.stable_id).or_insert_with(|| {
|
||||
file.name.display(RemapPathScopeComponents::COVERAGE).to_string_lossy().into_owned()
|
||||
// Prefer using the embeddable filename as this filename is going to
|
||||
// end-up in the coverage artifacts (see rust-lang/rust#150020).
|
||||
if let FileName::Real(real) = &file.name {
|
||||
let (_work_dir, abs_name) =
|
||||
real.embeddable_name(RemapPathScopeComponents::COVERAGE);
|
||||
|
||||
abs_name.to_string_lossy().into_owned()
|
||||
} else {
|
||||
file.name
|
||||
.display(RemapPathScopeComponents::COVERAGE)
|
||||
.to_string_lossy()
|
||||
.into_owned()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,17 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
|
||||
fn init(&self, sess: &Session) {
|
||||
llvm_util::init(sess); // Make sure llvm is inited
|
||||
|
||||
#[cfg(feature = "llvm_enzyme")]
|
||||
{
|
||||
use rustc_session::config::AutoDiff;
|
||||
|
||||
use crate::back::lto::enable_autodiff_settings;
|
||||
if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) {
|
||||
drop(llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot));
|
||||
enable_autodiff_settings(&sess.opts.unstable_opts.autodiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn provide(&self, providers: &mut Providers) {
|
||||
|
|
|
|||
|
|
@ -91,102 +91,363 @@ pub(crate) use self::Enzyme_AD::*;
|
|||
|
||||
#[cfg(feature = "llvm_enzyme")]
|
||||
pub(crate) mod Enzyme_AD {
|
||||
use std::ffi::{CString, c_char};
|
||||
use std::ffi::{c_char, c_void};
|
||||
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||
|
||||
use libc::c_void;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::{Sysroot, host_tuple};
|
||||
use rustc_session::filesearch;
|
||||
|
||||
use super::{CConcreteType, CTypeTreeRef, Context};
|
||||
use crate::llvm::{EnzymeTypeTree, LLVMRustVersionMajor};
|
||||
|
||||
unsafe extern "C" {
|
||||
pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
|
||||
pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char);
|
||||
type EnzymeSetCLBoolFn = unsafe extern "C" fn(*mut c_void, u8);
|
||||
type EnzymeSetCLStringFn = unsafe extern "C" fn(*mut c_void, *const c_char);
|
||||
|
||||
type EnzymeNewTypeTreeFn = unsafe extern "C" fn() -> CTypeTreeRef;
|
||||
type EnzymeNewTypeTreeCTFn = unsafe extern "C" fn(CConcreteType, &Context) -> CTypeTreeRef;
|
||||
type EnzymeNewTypeTreeTRFn = unsafe extern "C" fn(CTypeTreeRef) -> CTypeTreeRef;
|
||||
type EnzymeFreeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef);
|
||||
type EnzymeMergeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef, CTypeTreeRef) -> bool;
|
||||
type EnzymeTypeTreeOnlyEqFn = unsafe extern "C" fn(CTypeTreeRef, i64);
|
||||
type EnzymeTypeTreeData0EqFn = unsafe extern "C" fn(CTypeTreeRef);
|
||||
type EnzymeTypeTreeShiftIndiciesEqFn =
|
||||
unsafe extern "C" fn(CTypeTreeRef, *const c_char, i64, i64, u64);
|
||||
type EnzymeTypeTreeInsertEqFn =
|
||||
unsafe extern "C" fn(CTypeTreeRef, *const i64, usize, CConcreteType, &Context);
|
||||
type EnzymeTypeTreeToStringFn = unsafe extern "C" fn(CTypeTreeRef) -> *const c_char;
|
||||
type EnzymeTypeTreeToStringFreeFn = unsafe extern "C" fn(*const c_char);
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub(crate) struct EnzymeWrapper {
|
||||
EnzymeNewTypeTree: EnzymeNewTypeTreeFn,
|
||||
EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn,
|
||||
EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn,
|
||||
EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn,
|
||||
EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn,
|
||||
EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn,
|
||||
EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn,
|
||||
EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn,
|
||||
EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn,
|
||||
EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn,
|
||||
EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn,
|
||||
|
||||
EnzymePrintPerf: *mut c_void,
|
||||
EnzymePrintActivity: *mut c_void,
|
||||
EnzymePrintType: *mut c_void,
|
||||
EnzymeFunctionToAnalyze: *mut c_void,
|
||||
EnzymePrint: *mut c_void,
|
||||
EnzymeStrictAliasing: *mut c_void,
|
||||
EnzymeInline: *mut c_void,
|
||||
EnzymeMaxTypeDepth: *mut c_void,
|
||||
RustTypeRules: *mut c_void,
|
||||
looseTypeAnalysis: *mut c_void,
|
||||
|
||||
EnzymeSetCLBool: EnzymeSetCLBoolFn,
|
||||
EnzymeSetCLString: EnzymeSetCLStringFn,
|
||||
pub registerEnzymeAndPassPipeline: *const c_void,
|
||||
lib: libloading::Library,
|
||||
}
|
||||
|
||||
// TypeTree functions
|
||||
unsafe extern "C" {
|
||||
pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef;
|
||||
pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef;
|
||||
pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef;
|
||||
pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef);
|
||||
pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool;
|
||||
pub(crate) fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64);
|
||||
pub(crate) fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef);
|
||||
pub(crate) fn EnzymeTypeTreeShiftIndiciesEq(
|
||||
arg1: CTypeTreeRef,
|
||||
unsafe impl Sync for EnzymeWrapper {}
|
||||
unsafe impl Send for EnzymeWrapper {}
|
||||
|
||||
fn load_ptr_by_symbol_mut_void(
|
||||
lib: &libloading::Library,
|
||||
bytes: &[u8],
|
||||
) -> Result<*mut c_void, Box<dyn std::error::Error>> {
|
||||
unsafe {
|
||||
let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?;
|
||||
// libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some
|
||||
let s = s.try_as_raw_ptr().unwrap();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
||||
// e.g.
|
||||
// load_ptrs_by_symbols_mut_void(ABC, XYZ);
|
||||
// =>
|
||||
// let ABC = load_ptr_mut_void(&lib, b"ABC")?;
|
||||
// let XYZ = load_ptr_mut_void(&lib, b"XYZ")?;
|
||||
macro_rules! load_ptrs_by_symbols_mut_void {
|
||||
($lib:expr, $($name:ident),* $(,)?) => {
|
||||
$(
|
||||
#[allow(non_snake_case)]
|
||||
let $name = load_ptr_by_symbol_mut_void(&$lib, stringify!($name).as_bytes())?;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
// e.g.
|
||||
// load_ptrs_by_symbols_fn(ABC: ABCFn, XYZ: XYZFn);
|
||||
// =>
|
||||
// let ABC: libloading::Symbol<'_, ABCFn> = unsafe { lib.get(b"ABC")? };
|
||||
// let XYZ: libloading::Symbol<'_, XYZFn> = unsafe { lib.get(b"XYZ")? };
|
||||
macro_rules! load_ptrs_by_symbols_fn {
|
||||
($lib:expr, $($name:ident : $ty:ty),* $(,)?) => {
|
||||
$(
|
||||
#[allow(non_snake_case)]
|
||||
let $name: $ty = *unsafe { $lib.get::<$ty>(stringify!($name).as_bytes())? };
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
static ENZYME_INSTANCE: OnceLock<Mutex<EnzymeWrapper>> = OnceLock::new();
|
||||
|
||||
impl EnzymeWrapper {
|
||||
/// Initialize EnzymeWrapper with the given sysroot if not already initialized.
|
||||
/// Safe to call multiple times - subsequent calls are no-ops due to OnceLock.
|
||||
pub(crate) fn get_or_init(
|
||||
sysroot: &rustc_session::config::Sysroot,
|
||||
) -> MutexGuard<'static, Self> {
|
||||
ENZYME_INSTANCE
|
||||
.get_or_init(|| {
|
||||
Self::call_dynamic(sysroot)
|
||||
.unwrap_or_else(|e| bug!("failed to load Enzyme: {e}"))
|
||||
.into()
|
||||
})
|
||||
.lock()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Get the EnzymeWrapper instance. Panics if not initialized.
|
||||
pub(crate) fn get_instance() -> MutexGuard<'static, Self> {
|
||||
ENZYME_INSTANCE
|
||||
.get()
|
||||
.expect("EnzymeWrapper not initialized. Call get_or_init with sysroot first.")
|
||||
.lock()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn new_type_tree(&self) -> CTypeTreeRef {
|
||||
unsafe { (self.EnzymeNewTypeTree)() }
|
||||
}
|
||||
|
||||
pub(crate) fn new_type_tree_ct(
|
||||
&self,
|
||||
t: CConcreteType,
|
||||
ctx: &Context,
|
||||
) -> *mut EnzymeTypeTree {
|
||||
unsafe { (self.EnzymeNewTypeTreeCT)(t, ctx) }
|
||||
}
|
||||
|
||||
pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef {
|
||||
unsafe { (self.EnzymeNewTypeTreeTR)(tree) }
|
||||
}
|
||||
|
||||
pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) {
|
||||
unsafe { (self.EnzymeFreeTypeTree)(tree) }
|
||||
}
|
||||
|
||||
pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool {
|
||||
unsafe { (self.EnzymeMergeTypeTree)(tree1, tree2) }
|
||||
}
|
||||
|
||||
pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) {
|
||||
unsafe { (self.EnzymeTypeTreeOnlyEq)(tree, num) }
|
||||
}
|
||||
|
||||
pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) {
|
||||
unsafe { (self.EnzymeTypeTreeData0Eq)(tree) }
|
||||
}
|
||||
|
||||
pub(crate) fn shift_indicies_eq(
|
||||
&self,
|
||||
tree: CTypeTreeRef,
|
||||
data_layout: *const c_char,
|
||||
offset: i64,
|
||||
max_size: i64,
|
||||
add_offset: u64,
|
||||
);
|
||||
pub(crate) fn EnzymeTypeTreeInsertEq(
|
||||
CTT: CTypeTreeRef,
|
||||
) {
|
||||
unsafe {
|
||||
(self.EnzymeTypeTreeShiftIndiciesEq)(
|
||||
tree,
|
||||
data_layout,
|
||||
offset,
|
||||
max_size,
|
||||
add_offset,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn tree_insert_eq(
|
||||
&self,
|
||||
tree: CTypeTreeRef,
|
||||
indices: *const i64,
|
||||
len: usize,
|
||||
ct: CConcreteType,
|
||||
ctx: &Context,
|
||||
);
|
||||
pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char;
|
||||
pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char);
|
||||
}
|
||||
) {
|
||||
unsafe { (self.EnzymeTypeTreeInsertEq)(tree, indices, len, ct, ctx) }
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
static mut EnzymePrintPerf: c_void;
|
||||
static mut EnzymePrintActivity: c_void;
|
||||
static mut EnzymePrintType: c_void;
|
||||
static mut EnzymeFunctionToAnalyze: c_void;
|
||||
static mut EnzymePrint: c_void;
|
||||
static mut EnzymeStrictAliasing: c_void;
|
||||
static mut looseTypeAnalysis: c_void;
|
||||
static mut EnzymeInline: c_void;
|
||||
static mut RustTypeRules: c_void;
|
||||
}
|
||||
pub(crate) fn set_print_perf(print: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8);
|
||||
pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char {
|
||||
unsafe { (self.EnzymeTypeTreeToString)(tree) }
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_print_activity(print: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8);
|
||||
|
||||
pub(crate) fn tree_to_string_free(&self, ch: *const c_char) {
|
||||
unsafe { (self.EnzymeTypeTreeToStringFree)(ch) }
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_print_type(print: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8);
|
||||
|
||||
pub(crate) fn get_max_type_depth(&self) -> usize {
|
||||
unsafe { std::ptr::read::<u32>(self.EnzymeMaxTypeDepth as *const u32) as usize }
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_print_type_fun(fun_name: &str) {
|
||||
let c_fun_name = CString::new(fun_name).unwrap();
|
||||
unsafe {
|
||||
EnzymeSetCLString(
|
||||
std::ptr::addr_of_mut!(EnzymeFunctionToAnalyze),
|
||||
c_fun_name.as_ptr() as *const c_char,
|
||||
|
||||
pub(crate) fn set_print_perf(&mut self, print: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymePrintPerf, print as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_activity(&mut self, print: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymePrintActivity, print as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_type(&mut self, print: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymePrintType, print as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) {
|
||||
let c_fun_name = std::ffi::CString::new(fun_name)
|
||||
.unwrap_or_else(|err| bug!("failed to set_print_type_fun: {err}"));
|
||||
unsafe {
|
||||
(self.EnzymeSetCLString)(
|
||||
self.EnzymeFunctionToAnalyze,
|
||||
c_fun_name.as_ptr() as *const c_char,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_print(&mut self, print: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymePrint, print as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_strict_aliasing(&mut self, strict: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymeStrictAliasing, strict as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_loose_types(&mut self, loose: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.looseTypeAnalysis, loose as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_inline(&mut self, val: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.EnzymeInline, val as u8);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_rust_rules(&mut self, val: bool) {
|
||||
unsafe {
|
||||
(self.EnzymeSetCLBool)(self.RustTypeRules, val as u8);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn call_dynamic(
|
||||
sysroot: &rustc_session::config::Sysroot,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let enzyme_path = Self::get_enzyme_path(sysroot)?;
|
||||
let lib = unsafe { libloading::Library::new(enzyme_path)? };
|
||||
|
||||
load_ptrs_by_symbols_fn!(
|
||||
lib,
|
||||
EnzymeNewTypeTree: EnzymeNewTypeTreeFn,
|
||||
EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn,
|
||||
EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn,
|
||||
EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn,
|
||||
EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn,
|
||||
EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn,
|
||||
EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn,
|
||||
EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn,
|
||||
EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn,
|
||||
EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn,
|
||||
EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn,
|
||||
EnzymeSetCLBool: EnzymeSetCLBoolFn,
|
||||
EnzymeSetCLString: EnzymeSetCLStringFn,
|
||||
);
|
||||
|
||||
load_ptrs_by_symbols_mut_void!(
|
||||
lib,
|
||||
registerEnzymeAndPassPipeline,
|
||||
EnzymePrintPerf,
|
||||
EnzymePrintActivity,
|
||||
EnzymePrintType,
|
||||
EnzymeFunctionToAnalyze,
|
||||
EnzymePrint,
|
||||
EnzymeStrictAliasing,
|
||||
EnzymeInline,
|
||||
EnzymeMaxTypeDepth,
|
||||
RustTypeRules,
|
||||
looseTypeAnalysis,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
EnzymeNewTypeTree,
|
||||
EnzymeNewTypeTreeCT,
|
||||
EnzymeNewTypeTreeTR,
|
||||
EnzymeFreeTypeTree,
|
||||
EnzymeMergeTypeTree,
|
||||
EnzymeTypeTreeOnlyEq,
|
||||
EnzymeTypeTreeData0Eq,
|
||||
EnzymeTypeTreeShiftIndiciesEq,
|
||||
EnzymeTypeTreeInsertEq,
|
||||
EnzymeTypeTreeToString,
|
||||
EnzymeTypeTreeToStringFree,
|
||||
EnzymePrintPerf,
|
||||
EnzymePrintActivity,
|
||||
EnzymePrintType,
|
||||
EnzymeFunctionToAnalyze,
|
||||
EnzymePrint,
|
||||
EnzymeStrictAliasing,
|
||||
EnzymeInline,
|
||||
EnzymeMaxTypeDepth,
|
||||
RustTypeRules,
|
||||
looseTypeAnalysis,
|
||||
EnzymeSetCLBool,
|
||||
EnzymeSetCLString,
|
||||
registerEnzymeAndPassPipeline,
|
||||
lib,
|
||||
})
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_print(print: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8);
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_strict_aliasing(strict: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8);
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_loose_types(loose: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8);
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_inline(val: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8);
|
||||
}
|
||||
}
|
||||
pub(crate) fn set_rust_rules(val: bool) {
|
||||
unsafe {
|
||||
EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8);
|
||||
|
||||
fn get_enzyme_path(sysroot: &Sysroot) -> Result<String, String> {
|
||||
let llvm_version_major = unsafe { LLVMRustVersionMajor() };
|
||||
|
||||
let path_buf = sysroot
|
||||
.all_paths()
|
||||
.map(|sysroot_path| {
|
||||
filesearch::make_target_lib_path(sysroot_path, host_tuple())
|
||||
.join("lib")
|
||||
.with_file_name(format!("libEnzyme-{llvm_version_major}"))
|
||||
.with_extension(std::env::consts::DLL_EXTENSION)
|
||||
})
|
||||
.find(|f| f.exists())
|
||||
.ok_or_else(|| {
|
||||
let candidates = sysroot
|
||||
.all_paths()
|
||||
.map(|p| p.join("lib").display().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n* ");
|
||||
format!(
|
||||
"failed to find a `libEnzyme-{llvm_version_major}` folder \
|
||||
in the sysroot candidates:\n* {candidates}"
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(path_buf
|
||||
.to_str()
|
||||
.ok_or_else(|| format!("invalid UTF-8 in path: {}", path_buf.display()))?
|
||||
.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,111 +459,156 @@ pub(crate) use self::Fallback_AD::*;
|
|||
pub(crate) mod Fallback_AD {
|
||||
#![allow(unused_variables)]
|
||||
|
||||
use std::ffi::c_void;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
use libc::c_char;
|
||||
use rustc_codegen_ssa::back::write::CodegenContext;
|
||||
use rustc_codegen_ssa::traits::WriteBackendMethods;
|
||||
|
||||
use super::{CConcreteType, CTypeTreeRef, Context};
|
||||
use super::{CConcreteType, CTypeTreeRef, Context, EnzymeTypeTree};
|
||||
|
||||
// TypeTree function fallbacks
|
||||
pub(crate) unsafe fn EnzymeNewTypeTree() -> CTypeTreeRef {
|
||||
unimplemented!()
|
||||
pub(crate) struct EnzymeWrapper {
|
||||
pub registerEnzymeAndPassPipeline: *const c_void,
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef {
|
||||
unimplemented!()
|
||||
}
|
||||
impl EnzymeWrapper {
|
||||
pub(crate) fn get_or_init(
|
||||
_sysroot: &rustc_session::config::Sysroot,
|
||||
) -> MutexGuard<'static, Self> {
|
||||
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn init<'a, B: WriteBackendMethods>(
|
||||
_cgcx: &'a CodegenContext<B>,
|
||||
) -> &'static Mutex<Self> {
|
||||
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeFreeTypeTree(CTT: CTypeTreeRef) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn get_instance() -> MutexGuard<'static, Self> {
|
||||
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn new_type_tree(&self) -> CTypeTreeRef {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn new_type_tree_ct(
|
||||
&self,
|
||||
t: CConcreteType,
|
||||
ctx: &Context,
|
||||
) -> *mut EnzymeTypeTree {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeShiftIndiciesEq(
|
||||
arg1: CTypeTreeRef,
|
||||
data_layout: *const c_char,
|
||||
offset: i64,
|
||||
max_size: i64,
|
||||
add_offset: u64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeInsertEq(
|
||||
CTT: CTypeTreeRef,
|
||||
indices: *const i64,
|
||||
len: usize,
|
||||
ct: CConcreteType,
|
||||
ctx: &Context,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn EnzymeTypeTreeToStringFree(arg1: *const c_char) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_inline(val: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_print_perf(print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_print_activity(print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_print_type(print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_print_type_fun(fun_name: &str) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_print(print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_strict_aliasing(strict: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_loose_types(loose: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
pub(crate) fn set_rust_rules(val: bool) {
|
||||
unimplemented!()
|
||||
pub(crate) fn shift_indicies_eq(
|
||||
&self,
|
||||
tree: CTypeTreeRef,
|
||||
data_layout: *const c_char,
|
||||
offset: i64,
|
||||
max_size: i64,
|
||||
add_offset: u64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn tree_insert_eq(
|
||||
&self,
|
||||
tree: CTypeTreeRef,
|
||||
indices: *const i64,
|
||||
len: usize,
|
||||
ct: CConcreteType,
|
||||
ctx: &Context,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn tree_to_string_free(&self, ch: *const c_char) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn get_max_type_depth(&self) -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_inline(&mut self, val: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_perf(&mut self, print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_activity(&mut self, print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_type(&mut self, print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_print(&mut self, print: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_strict_aliasing(&mut self, strict: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_loose_types(&mut self, loose: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) fn set_rust_rules(&mut self, val: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeTree {
|
||||
pub(crate) fn new() -> TypeTree {
|
||||
let inner = unsafe { EnzymeNewTypeTree() };
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
let inner = wrapper.new_type_tree();
|
||||
TypeTree { inner }
|
||||
}
|
||||
|
||||
pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree {
|
||||
let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) };
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
let inner = wrapper.new_type_tree_ct(t, ctx);
|
||||
TypeTree { inner }
|
||||
}
|
||||
|
||||
pub(crate) fn merge(self, other: Self) -> Self {
|
||||
unsafe {
|
||||
EnzymeMergeTypeTree(self.inner, other.inner);
|
||||
}
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
wrapper.merge_type_tree(self.inner, other.inner);
|
||||
drop(other);
|
||||
self
|
||||
}
|
||||
|
|
@ -316,37 +622,36 @@ impl TypeTree {
|
|||
add_offset: usize,
|
||||
) -> Self {
|
||||
let layout = std::ffi::CString::new(layout).unwrap();
|
||||
|
||||
unsafe {
|
||||
EnzymeTypeTreeShiftIndiciesEq(
|
||||
self.inner,
|
||||
layout.as_ptr(),
|
||||
offset as i64,
|
||||
max_size as i64,
|
||||
add_offset as u64,
|
||||
);
|
||||
}
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
wrapper.shift_indicies_eq(
|
||||
self.inner,
|
||||
layout.as_ptr(),
|
||||
offset as i64,
|
||||
max_size as i64,
|
||||
add_offset as u64,
|
||||
);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn insert(&mut self, indices: &[i64], ct: CConcreteType, ctx: &Context) {
|
||||
unsafe {
|
||||
EnzymeTypeTreeInsertEq(self.inner, indices.as_ptr(), indices.len(), ct, ctx);
|
||||
}
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
wrapper.tree_insert_eq(self.inner, indices.as_ptr(), indices.len(), ct, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for TypeTree {
|
||||
fn clone(&self) -> Self {
|
||||
let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) };
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
let inner = wrapper.new_type_tree_tr(self.inner);
|
||||
TypeTree { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for TypeTree {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let ptr = unsafe { EnzymeTypeTreeToString(self.inner) };
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
let ptr = wrapper.tree_to_string(self.inner);
|
||||
let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) };
|
||||
match cstr.to_str() {
|
||||
Ok(x) => write!(f, "{}", x)?,
|
||||
|
|
@ -354,9 +659,7 @@ impl std::fmt::Display for TypeTree {
|
|||
}
|
||||
|
||||
// delete C string pointer
|
||||
unsafe {
|
||||
EnzymeTypeTreeToStringFree(ptr);
|
||||
}
|
||||
wrapper.tree_to_string_free(ptr);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -370,6 +673,7 @@ impl std::fmt::Debug for TypeTree {
|
|||
|
||||
impl Drop for TypeTree {
|
||||
fn drop(&mut self) {
|
||||
unsafe { EnzymeFreeTypeTree(self.inner) }
|
||||
let wrapper = EnzymeWrapper::get_instance();
|
||||
wrapper.free_type_tree(self.inner)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2411,7 +2411,7 @@ unsafe extern "C" {
|
|||
LoopVectorize: bool,
|
||||
DisableSimplifyLibCalls: bool,
|
||||
EmitLifetimeMarkers: bool,
|
||||
RunEnzyme: bool,
|
||||
RunEnzyme: *const c_void,
|
||||
PrintBeforeEnzyme: bool,
|
||||
PrintAfterEnzyme: bool,
|
||||
PrintPasses: bool,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_ast::expand::typetree::FncTree;
|
|||
#[cfg(feature = "llvm_enzyme")]
|
||||
use {
|
||||
crate::attributes,
|
||||
crate::llvm::EnzymeWrapper,
|
||||
rustc_ast::expand::typetree::TypeTree as RustTypeTree,
|
||||
std::ffi::{CString, c_char, c_uint},
|
||||
};
|
||||
|
|
@ -77,7 +78,8 @@ pub(crate) fn add_tt<'ll>(
|
|||
for (i, input) in inputs.iter().enumerate() {
|
||||
unsafe {
|
||||
let enzyme_tt = to_enzyme_typetree(input.clone(), llvm_data_layout, llcx);
|
||||
let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner);
|
||||
let enzyme_wrapper = EnzymeWrapper::get_instance();
|
||||
let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner);
|
||||
let c_str = std::ffi::CStr::from_ptr(c_str);
|
||||
|
||||
let attr = llvm::LLVMCreateStringAttribute(
|
||||
|
|
@ -89,13 +91,14 @@ pub(crate) fn add_tt<'ll>(
|
|||
);
|
||||
|
||||
attributes::apply_to_llfn(fn_def, llvm::AttributePlace::Argument(i as u32), &[attr]);
|
||||
llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr());
|
||||
enzyme_wrapper.tree_to_string_free(c_str.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let enzyme_tt = to_enzyme_typetree(ret_tt, llvm_data_layout, llcx);
|
||||
let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner);
|
||||
let enzyme_wrapper = EnzymeWrapper::get_instance();
|
||||
let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner);
|
||||
let c_str = std::ffi::CStr::from_ptr(c_str);
|
||||
|
||||
let ret_attr = llvm::LLVMCreateStringAttribute(
|
||||
|
|
@ -107,7 +110,7 @@ pub(crate) fn add_tt<'ll>(
|
|||
);
|
||||
|
||||
attributes::apply_to_llfn(fn_def, llvm::AttributePlace::ReturnValue, &[ret_attr]);
|
||||
llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr());
|
||||
enzyme_wrapper.tree_to_string_free(c_str.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2792,11 +2792,9 @@ fn add_upstream_rust_crates(
|
|||
// We must always link crates `compiler_builtins` and `profiler_builtins` statically.
|
||||
// Even if they were already included into a dylib
|
||||
// (e.g. `libstd` when `-C prefer-dynamic` is used).
|
||||
// FIXME: `dependency_formats` can report `profiler_builtins` as `NotLinked` for some
|
||||
// reason, it shouldn't do that because `profiler_builtins` should indeed be linked.
|
||||
let linkage = data[cnum];
|
||||
let link_static_crate = linkage == Linkage::Static
|
||||
|| (linkage == Linkage::IncludedFromDylib || linkage == Linkage::NotLinked)
|
||||
|| linkage == Linkage::IncludedFromDylib
|
||||
&& (codegen_results.crate_info.compiler_builtins == Some(cnum)
|
||||
|| codegen_results.crate_info.profiler_runtime == Some(cnum));
|
||||
|
||||
|
|
|
|||
|
|
@ -178,19 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
ty::Never if is_input => return None,
|
||||
_ if ty.references_error() => return None,
|
||||
ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::ONE].ty(self.tcx(), args);
|
||||
// FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
|
||||
// If so, just get it from the args.
|
||||
let ty::Adt(ty, args) = ty.kind() else {
|
||||
unreachable!("expected first field of `MaybeUninit` to be an ADT")
|
||||
};
|
||||
assert!(
|
||||
ty.is_manually_drop(),
|
||||
"expected first field of `MaybeUninit` to be `ManuallyDrop`"
|
||||
);
|
||||
let fields = &ty.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args);
|
||||
let ty = args.type_at(0);
|
||||
self.get_asm_ty(expr.span, ty)
|
||||
}
|
||||
_ => self.get_asm_ty(expr.span, ty),
|
||||
|
|
|
|||
|
|
@ -550,17 +550,8 @@ struct LLVMRustSanitizerOptions {
|
|||
bool SanitizeKernelAddressRecover;
|
||||
};
|
||||
|
||||
// This symbol won't be available or used when Enzyme is not enabled.
|
||||
// Always set AugmentPassBuilder to true, since it registers optimizations which
|
||||
// will improve the performance for Enzyme.
|
||||
#ifdef ENZYME
|
||||
extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB,
|
||||
/* augmentPassBuilder */ bool);
|
||||
|
||||
extern "C" {
|
||||
extern llvm::cl::opt<std::string> EnzymeFunctionToAnalyze;
|
||||
}
|
||||
#endif
|
||||
extern "C" typedef void (*registerEnzymeAndPassPipelineFn)(
|
||||
llvm::PassBuilder &PB, bool augment);
|
||||
|
||||
extern "C" LLVMRustResult LLVMRustOptimize(
|
||||
LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
|
||||
|
|
@ -569,8 +560,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO,
|
||||
bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops,
|
||||
bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
|
||||
bool EmitLifetimeMarkers, bool RunEnzyme, bool PrintBeforeEnzyme,
|
||||
bool PrintAfterEnzyme, bool PrintPasses,
|
||||
bool EmitLifetimeMarkers, registerEnzymeAndPassPipelineFn EnzymePtr,
|
||||
bool PrintBeforeEnzyme, bool PrintAfterEnzyme, bool PrintPasses,
|
||||
LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath,
|
||||
const char *PGOUsePath, bool InstrumentCoverage,
|
||||
const char *InstrProfileOutput, const char *PGOSampleUsePath,
|
||||
|
|
@ -907,8 +898,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
}
|
||||
|
||||
// now load "-enzyme" pass:
|
||||
#ifdef ENZYME
|
||||
if (RunEnzyme) {
|
||||
// With dlopen, ENZYME macro may not be defined, so check EnzymePtr directly
|
||||
if (EnzymePtr) {
|
||||
|
||||
if (PrintBeforeEnzyme) {
|
||||
// Handle the Rust flag `-Zautodiff=PrintModBefore`.
|
||||
|
|
@ -916,29 +907,19 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
MPM.addPass(PrintModulePass(outs(), Banner, true, false));
|
||||
}
|
||||
|
||||
registerEnzymeAndPassPipeline(PB, false);
|
||||
EnzymePtr(PB, false);
|
||||
if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) {
|
||||
std::string ErrMsg = toString(std::move(Err));
|
||||
LLVMRustSetLastError(ErrMsg.c_str());
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
|
||||
// Check if PrintTAFn was used and add type analysis pass if needed
|
||||
if (!EnzymeFunctionToAnalyze.empty()) {
|
||||
if (auto Err = PB.parsePassPipeline(MPM, "print-type-analysis")) {
|
||||
std::string ErrMsg = toString(std::move(Err));
|
||||
LLVMRustSetLastError(ErrMsg.c_str());
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (PrintAfterEnzyme) {
|
||||
// Handle the Rust flag `-Zautodiff=PrintModAfter`.
|
||||
std::string Banner = "Module after EnzymeNewPM";
|
||||
MPM.addPass(PrintModulePass(outs(), Banner, true, false));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (PrintPasses) {
|
||||
// Print all passes from the PM:
|
||||
std::string Pipeline;
|
||||
|
|
|
|||
|
|
@ -1791,18 +1791,6 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
|
|||
GV.setSanitizerMetadata(MD);
|
||||
}
|
||||
|
||||
#ifdef ENZYME
|
||||
extern "C" {
|
||||
extern llvm::cl::opt<unsigned> EnzymeMaxTypeDepth;
|
||||
}
|
||||
|
||||
extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() { return EnzymeMaxTypeDepth; }
|
||||
#else
|
||||
extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() {
|
||||
return 6; // Default fallback depth
|
||||
}
|
||||
#endif
|
||||
|
||||
// Statically assert that the fixed metadata kind IDs declared in
|
||||
// `metadata_kind.rs` match the ones actually used by LLVM.
|
||||
#define FIXED_MD_KIND(VARIANT, VALUE) \
|
||||
|
|
|
|||
|
|
@ -156,8 +156,8 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
|
|||
enum CrateOrigin<'a> {
|
||||
/// This crate was a dependency of another crate.
|
||||
IndirectDependency {
|
||||
/// Where this dependency was included from.
|
||||
dep_root: &'a CratePaths,
|
||||
/// Where this dependency was included from. Should only be used in error messages.
|
||||
dep_root_for_errors: &'a CratePaths,
|
||||
/// True if the parent is private, meaning the dependent should also be private.
|
||||
parent_private: bool,
|
||||
/// Dependency info about this crate.
|
||||
|
|
@ -171,9 +171,11 @@ enum CrateOrigin<'a> {
|
|||
|
||||
impl<'a> CrateOrigin<'a> {
|
||||
/// Return the dependency root, if any.
|
||||
fn dep_root(&self) -> Option<&'a CratePaths> {
|
||||
fn dep_root_for_errors(&self) -> Option<&'a CratePaths> {
|
||||
match self {
|
||||
CrateOrigin::IndirectDependency { dep_root, .. } => Some(dep_root),
|
||||
CrateOrigin::IndirectDependency { dep_root_for_errors, .. } => {
|
||||
Some(dep_root_for_errors)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +195,7 @@ impl<'a> CrateOrigin<'a> {
|
|||
CrateOrigin::IndirectDependency { parent_private, dep, .. } => {
|
||||
Some(dep.is_private || *parent_private)
|
||||
}
|
||||
CrateOrigin::Injected => Some(true),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -544,17 +547,7 @@ impl CStore {
|
|||
/// Sometimes the directly dependent crate is not specified by `--extern`, in this case,
|
||||
/// `private-dep` is none during loading. This is equivalent to the scenario where the
|
||||
/// command parameter is set to `public-dependency`
|
||||
fn is_private_dep(
|
||||
&self,
|
||||
externs: &Externs,
|
||||
name: Symbol,
|
||||
private_dep: Option<bool>,
|
||||
origin: CrateOrigin<'_>,
|
||||
) -> bool {
|
||||
if matches!(origin, CrateOrigin::Injected) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn is_private_dep(&self, externs: &Externs, name: Symbol, private_dep: Option<bool>) -> bool {
|
||||
let extern_private = externs.get(name.as_str()).map(|e| e.is_private_dep);
|
||||
match (extern_private, private_dep) {
|
||||
// Explicit non-private via `--extern`, explicit non-private from metadata, or
|
||||
|
|
@ -581,7 +574,7 @@ impl CStore {
|
|||
let Library { source, metadata } = lib;
|
||||
let crate_root = metadata.get_root();
|
||||
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
|
||||
let private_dep = self.is_private_dep(&tcx.sess.opts.externs, name, private_dep, origin);
|
||||
let private_dep = self.is_private_dep(&tcx.sess.opts.externs, name, private_dep);
|
||||
|
||||
// Claim this crate number and cache it
|
||||
let feed = self.intern_stable_crate_id(tcx, &crate_root)?;
|
||||
|
|
@ -597,8 +590,8 @@ impl CStore {
|
|||
// Maintain a reference to the top most crate.
|
||||
// Stash paths for top-most crate locally if necessary.
|
||||
let crate_paths;
|
||||
let dep_root = if let Some(dep_root) = origin.dep_root() {
|
||||
dep_root
|
||||
let dep_root_for_errors = if let Some(dep_root_for_errors) = origin.dep_root_for_errors() {
|
||||
dep_root_for_errors
|
||||
} else {
|
||||
crate_paths = CratePaths::new(crate_root.name(), source.clone());
|
||||
&crate_paths
|
||||
|
|
@ -606,7 +599,7 @@ impl CStore {
|
|||
|
||||
let cnum_map = self.resolve_crate_deps(
|
||||
tcx,
|
||||
dep_root,
|
||||
dep_root_for_errors,
|
||||
&crate_root,
|
||||
&metadata,
|
||||
cnum,
|
||||
|
|
@ -726,7 +719,7 @@ impl CStore {
|
|||
self.used_extern_options.insert(name);
|
||||
match self.maybe_resolve_crate(tcx, name, dep_kind, origin) {
|
||||
Ok(cnum) => {
|
||||
self.set_used_recursively(tcx, cnum);
|
||||
self.set_used_recursively(cnum);
|
||||
Some(cnum)
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
@ -735,7 +728,7 @@ impl CStore {
|
|||
.maybe_resolve_crate(
|
||||
tcx,
|
||||
sym::core,
|
||||
CrateDepKind::Explicit,
|
||||
CrateDepKind::Unconditional,
|
||||
CrateOrigin::Extern,
|
||||
)
|
||||
.is_err();
|
||||
|
|
@ -757,7 +750,7 @@ impl CStore {
|
|||
return Err(CrateError::NonAsciiName(name));
|
||||
}
|
||||
|
||||
let dep_root = origin.dep_root();
|
||||
let dep_root_for_errors = origin.dep_root_for_errors();
|
||||
let dep = origin.dep();
|
||||
let hash = dep.map(|d| d.hash);
|
||||
let host_hash = dep.map(|d| d.host_hash).flatten();
|
||||
|
|
@ -795,7 +788,11 @@ impl CStore {
|
|||
host_hash,
|
||||
)? {
|
||||
Some(res) => res,
|
||||
None => return Err(locator.into_error(crate_rejections, dep_root.cloned())),
|
||||
None => {
|
||||
return Err(
|
||||
locator.into_error(crate_rejections, dep_root_for_errors.cloned())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -808,8 +805,7 @@ impl CStore {
|
|||
// not specified by `--extern` on command line parameters, it may be
|
||||
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
|
||||
// `public-dependency` here.
|
||||
let private_dep =
|
||||
self.is_private_dep(&tcx.sess.opts.externs, name, private_dep, origin);
|
||||
let private_dep = self.is_private_dep(&tcx.sess.opts.externs, name, private_dep);
|
||||
let data = self.get_crate_data_mut(cnum);
|
||||
if data.is_proc_macro_crate() {
|
||||
dep_kind = CrateDepKind::MacrosOnly;
|
||||
|
|
@ -856,7 +852,7 @@ impl CStore {
|
|||
fn resolve_crate_deps(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
dep_root: &CratePaths,
|
||||
dep_root_for_errors: &CratePaths,
|
||||
crate_root: &CrateRoot,
|
||||
metadata: &MetadataBlob,
|
||||
krate: CrateNum,
|
||||
|
|
@ -866,7 +862,7 @@ impl CStore {
|
|||
debug!(
|
||||
"resolving deps of external crate `{}` with dep root `{}`",
|
||||
crate_root.name(),
|
||||
dep_root.name
|
||||
dep_root_for_errors.name
|
||||
);
|
||||
if crate_root.is_proc_macro_crate() {
|
||||
return Ok(CrateNumMap::new());
|
||||
|
|
@ -896,7 +892,7 @@ impl CStore {
|
|||
dep.name,
|
||||
dep_kind,
|
||||
CrateOrigin::IndirectDependency {
|
||||
dep_root,
|
||||
dep_root_for_errors,
|
||||
parent_private: parent_is_private,
|
||||
dep: &dep,
|
||||
},
|
||||
|
|
@ -979,9 +975,15 @@ impl CStore {
|
|||
};
|
||||
info!("panic runtime not found -- loading {}", name);
|
||||
|
||||
let Some(cnum) =
|
||||
self.resolve_crate(tcx, name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
|
||||
else {
|
||||
// This has to be conditional as both panic_unwind and panic_abort may be present in the
|
||||
// crate graph at the same time. One of them will later be activated in dependency_formats.
|
||||
let Some(cnum) = self.resolve_crate(
|
||||
tcx,
|
||||
name,
|
||||
DUMMY_SP,
|
||||
CrateDepKind::Conditional,
|
||||
CrateOrigin::Injected,
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
let data = self.get_crate_data(cnum);
|
||||
|
|
@ -1009,9 +1011,13 @@ impl CStore {
|
|||
info!("loading profiler");
|
||||
|
||||
let name = Symbol::intern(&tcx.sess.opts.unstable_opts.profiler_runtime);
|
||||
let Some(cnum) =
|
||||
self.resolve_crate(tcx, name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
|
||||
else {
|
||||
let Some(cnum) = self.resolve_crate(
|
||||
tcx,
|
||||
name,
|
||||
DUMMY_SP,
|
||||
CrateDepKind::Unconditional,
|
||||
CrateOrigin::Injected,
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
let data = self.get_crate_data(cnum);
|
||||
|
|
@ -1131,7 +1137,7 @@ impl CStore {
|
|||
tcx,
|
||||
name_interned,
|
||||
DUMMY_SP,
|
||||
CrateDepKind::Explicit,
|
||||
CrateDepKind::Unconditional,
|
||||
CrateOrigin::Extern,
|
||||
);
|
||||
}
|
||||
|
|
@ -1163,7 +1169,7 @@ impl CStore {
|
|||
tcx,
|
||||
sym::compiler_builtins,
|
||||
krate.spans.inner_span.shrink_to_lo(),
|
||||
CrateDepKind::Explicit,
|
||||
CrateDepKind::Unconditional,
|
||||
CrateOrigin::Injected,
|
||||
) else {
|
||||
info!("`compiler_builtins` not resolved");
|
||||
|
|
@ -1280,7 +1286,7 @@ impl CStore {
|
|||
let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
|
||||
CrateDepKind::MacrosOnly
|
||||
} else {
|
||||
CrateDepKind::Explicit
|
||||
CrateDepKind::Unconditional
|
||||
};
|
||||
|
||||
let cnum =
|
||||
|
|
@ -1310,7 +1316,7 @@ impl CStore {
|
|||
span: Span,
|
||||
) -> Option<CrateNum> {
|
||||
let cnum =
|
||||
self.resolve_crate(tcx, name, span, CrateDepKind::Explicit, CrateOrigin::Extern)?;
|
||||
self.resolve_crate(tcx, name, span, CrateDepKind::Unconditional, CrateOrigin::Extern)?;
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
|
|
@ -1328,7 +1334,7 @@ impl CStore {
|
|||
}
|
||||
|
||||
pub fn maybe_process_path_extern(&mut self, tcx: TyCtxt<'_>, name: Symbol) -> Option<CrateNum> {
|
||||
self.maybe_resolve_crate(tcx, name, CrateDepKind::Explicit, CrateOrigin::Extern).ok()
|
||||
self.maybe_resolve_crate(tcx, name, CrateDepKind::Unconditional, CrateOrigin::Extern).ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
|||
let src = tcx.used_crate_source(cnum);
|
||||
if src.dylib.is_none()
|
||||
&& !formats.contains_key(&cnum)
|
||||
&& tcx.dep_kind(cnum) == CrateDepKind::Explicit
|
||||
&& tcx.dep_kind(cnum) == CrateDepKind::Unconditional
|
||||
{
|
||||
assert!(src.rlib.is_some() || src.rmeta.is_some());
|
||||
info!("adding staticlib: {}", tcx.crate_name(cnum));
|
||||
|
|
@ -355,8 +355,8 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
|
|||
for &cnum in tcx.crates(()) {
|
||||
assert_eq!(
|
||||
ret.push(match tcx.dep_kind(cnum) {
|
||||
CrateDepKind::Explicit => Linkage::Static,
|
||||
CrateDepKind::MacrosOnly | CrateDepKind::Implicit => Linkage::NotLinked,
|
||||
CrateDepKind::Unconditional => Linkage::Static,
|
||||
CrateDepKind::MacrosOnly | CrateDepKind::Conditional => Linkage::NotLinked,
|
||||
}),
|
||||
cnum
|
||||
);
|
||||
|
|
|
|||
|
|
@ -116,8 +116,6 @@ pub(crate) struct CrateMetadata {
|
|||
/// Maps crate IDs as they are were seen from this crate's compilation sessions into
|
||||
/// IDs as they are seen from the current compilation session.
|
||||
cnum_map: CrateNumMap,
|
||||
/// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
|
||||
dependencies: Vec<CrateNum>,
|
||||
/// How to link (or not link) this crate to the currently compiled crate.
|
||||
dep_kind: CrateDepKind,
|
||||
/// Filesystem location of this crate.
|
||||
|
|
@ -1897,7 +1895,6 @@ impl CrateMetadata {
|
|||
.collect();
|
||||
let alloc_decoding_state =
|
||||
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
|
||||
let dependencies = cnum_map.iter().copied().collect();
|
||||
|
||||
// Pre-decode the DefPathHash->DefIndex table. This is a cheap operation
|
||||
// that does not copy any data. It just does some data verification.
|
||||
|
|
@ -1915,7 +1912,6 @@ impl CrateMetadata {
|
|||
alloc_decoding_state,
|
||||
cnum,
|
||||
cnum_map,
|
||||
dependencies,
|
||||
dep_kind,
|
||||
source: Arc::new(source),
|
||||
private_dep,
|
||||
|
|
@ -1941,7 +1937,7 @@ impl CrateMetadata {
|
|||
}
|
||||
|
||||
pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> {
|
||||
self.dependencies.iter().copied()
|
||||
self.cnum_map.iter().copied()
|
||||
}
|
||||
|
||||
pub(crate) fn target_modifiers(&self) -> TargetModifiers {
|
||||
|
|
|
|||
|
|
@ -623,15 +623,15 @@ impl CStore {
|
|||
self.get_crate_data(cnum).get_proc_macro_quoted_span(tcx, id)
|
||||
}
|
||||
|
||||
pub fn set_used_recursively(&mut self, tcx: TyCtxt<'_>, cnum: CrateNum) {
|
||||
pub fn set_used_recursively(&mut self, cnum: CrateNum) {
|
||||
let cmeta = self.get_crate_data_mut(cnum);
|
||||
if !cmeta.used {
|
||||
cmeta.used = true;
|
||||
let dependencies = mem::take(&mut cmeta.dependencies);
|
||||
for &dep_cnum in &dependencies {
|
||||
self.set_used_recursively(tcx, dep_cnum);
|
||||
let cnum_map = mem::take(&mut cmeta.cnum_map);
|
||||
for &dep_cnum in cnum_map.iter() {
|
||||
self.set_used_recursively(dep_cnum);
|
||||
}
|
||||
self.get_crate_data_mut(cnum).dependencies = dependencies;
|
||||
self.get_crate_data_mut(cnum).cnum_map = cnum_map;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -663,11 +663,11 @@ impl CStore {
|
|||
if cmeta.update_extern_crate_diagnostics(extern_crate) {
|
||||
// Propagate the extern crate info to dependencies if it was updated.
|
||||
let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
|
||||
let dependencies = mem::take(&mut cmeta.dependencies);
|
||||
for &dep_cnum in &dependencies {
|
||||
let cnum_map = mem::take(&mut cmeta.cnum_map);
|
||||
for &dep_cnum in cnum_map.iter() {
|
||||
self.update_transitive_extern_crate_diagnostics(dep_cnum, extern_crate);
|
||||
}
|
||||
self.get_crate_data_mut(cnum).dependencies = dependencies;
|
||||
self.get_crate_data_mut(cnum).cnum_map = cnum_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -743,10 +743,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {
|
||||
Some(AmbiguityKind::BuiltinAttr)
|
||||
} else if innermost_res == derive_helper_compat
|
||||
|| res == derive_helper_compat && innermost_res != derive_helper
|
||||
{
|
||||
} else if innermost_res == derive_helper_compat {
|
||||
Some(AmbiguityKind::DeriveHelper)
|
||||
} else if res == derive_helper_compat && innermost_res != derive_helper {
|
||||
span_bug!(orig_ident.span, "impossible inner resolution kind")
|
||||
} else if innermost_flags.contains(Flags::MACRO_RULES)
|
||||
&& flags.contains(Flags::MODULE)
|
||||
&& !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding)
|
||||
|
|
|
|||
|
|
@ -39,12 +39,13 @@ impl CrateSource {
|
|||
pub enum CrateDepKind {
|
||||
/// A dependency that is only used for its macros.
|
||||
MacrosOnly,
|
||||
/// A dependency that is always injected into the dependency list and so
|
||||
/// doesn't need to be linked to an rlib, e.g., the injected panic runtime.
|
||||
Implicit,
|
||||
/// A dependency that is injected into the crate graph but which only
|
||||
/// sometimes needs to actually be linked in, e.g., the injected panic runtime.
|
||||
Conditional,
|
||||
/// A dependency that is required by an rlib version of this crate.
|
||||
/// Ordinary `extern crate`s result in `Explicit` dependencies.
|
||||
Explicit,
|
||||
/// Ordinary `extern crate`s as well as most injected dependencies result
|
||||
/// in `Unconditional` dependencies.
|
||||
Unconditional,
|
||||
}
|
||||
|
||||
impl CrateDepKind {
|
||||
|
|
@ -52,7 +53,7 @@ impl CrateDepKind {
|
|||
pub fn macros_only(self) -> bool {
|
||||
match self {
|
||||
CrateDepKind::MacrosOnly => true,
|
||||
CrateDepKind::Implicit | CrateDepKind::Explicit => false,
|
||||
CrateDepKind::Conditional | CrateDepKind::Unconditional => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1686,6 +1686,7 @@ supported_targets! {
|
|||
("riscv32imac-unknown-xous-elf", riscv32imac_unknown_xous_elf),
|
||||
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
|
||||
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
|
||||
("riscv64im-unknown-none-elf", riscv64im_unknown_none_elf),
|
||||
("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf),
|
||||
("riscv64gc-unknown-none-elf", riscv64gc_unknown_none_elf),
|
||||
("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
use crate::spec::{
|
||||
Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata,
|
||||
TargetOptions,
|
||||
};
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
|
||||
llvm_target: "riscv64".into(),
|
||||
metadata: TargetMetadata {
|
||||
description: Some("Bare RISC-V (RV64IM ISA)".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
arch: Arch::RiscV64,
|
||||
|
||||
options: TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
|
||||
linker: Some("rust-lld".into()),
|
||||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
atomic_cas: false,
|
||||
features: "+m,+forced-atomics".into(),
|
||||
llvm_abiname: "lp64".into(),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
emit_debug_gdb_scripts: false,
|
||||
eh_frame_header: false,
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@ nightly = [
|
|||
"dep:rustc_span",
|
||||
"rustc_ast_ir/nightly",
|
||||
"rustc_index/nightly",
|
||||
"rustc_type_ir_macros/nightly",
|
||||
"smallvec/may_dangle",
|
||||
"smallvec/union",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::ops::{ControlFlow, Deref};
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::data_structures::SsoHashSet;
|
||||
|
|
@ -25,6 +25,7 @@ use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex};
|
|||
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct Binder<I: Interner, T> {
|
||||
value: T,
|
||||
|
|
@ -361,6 +362,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
|||
#[derive_where(Clone, PartialEq, Ord, Hash, Debug; I: Interner, T)]
|
||||
#[derive_where(PartialOrd; I: Interner, T: Ord)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -944,7 +946,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> {
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub enum BoundVarIndexKind {
|
||||
Bound(DebruijnIndex),
|
||||
Canonical,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ use arrayvec::ArrayVec;
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::data_structures::HashMap;
|
||||
use crate::inherent::*;
|
||||
|
|
@ -86,6 +88,7 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
|
|||
/// a copy of the canonical value in some other inference context,
|
||||
/// with fresh inference variables replacing the canonical values.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -219,7 +222,7 @@ impl<I: Interner> CanonicalVarKind<I> {
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CanonicalVarValues<I: Interner> {
|
||||
pub var_values: I::GenericArgs,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@ use derive_where::derive_where;
|
|||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::{self as ty, BoundVarIndexKind, Interner};
|
||||
|
||||
/// Represents a constant in Rust.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -66,7 +69,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
|
|||
|
||||
/// An unevaluated (potentially generic) constant used in the type-system.
|
||||
#[derive_where(Clone, Copy, Debug, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::solve::NoSolution;
|
||||
use crate::{self as ty, Interner};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(TypeFoldable_Generic, TypeVisitable_Generic)]
|
||||
#[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)]
|
||||
pub struct ExpectedFound<T> {
|
||||
pub expected: T,
|
||||
pub found: T,
|
||||
|
|
@ -19,7 +19,7 @@ impl<T> ExpectedFound<T> {
|
|||
|
||||
// Data structures used in type unification
|
||||
#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable)]
|
||||
#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
|
||||
pub enum TypeError<I: Interner> {
|
||||
Mismatch,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::GenericTypeVisitable;
|
||||
|
||||
use crate::Interner;
|
||||
|
||||
#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -18,6 +20,7 @@ pub enum GenericArgKind<I: Interner> {
|
|||
impl<I: Interner> Eq for GenericArgKind<I> {}
|
||||
|
||||
#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
251
compiler/rustc_type_ir/src/generic_visit.rs
Normal file
251
compiler/rustc_type_ir/src/generic_visit.rs
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
//! A visiting traversal mechanism for complex data structures that contain type
|
||||
//! information.
|
||||
//!
|
||||
//! This is a read-only traversal of the data structure.
|
||||
//!
|
||||
//! This traversal has limited flexibility. Only a small number of "types of
|
||||
//! interest" within the complex data structures can receive custom
|
||||
//! visitation. These are the ones containing the most important type-related
|
||||
//! information, such as `Ty`, `Predicate`, `Region`, and `Const`.
|
||||
//!
|
||||
//! There are three traits involved in each traversal.
|
||||
//! - `GenericTypeVisitable`. This is implemented once for many types, including:
|
||||
//! - Types of interest, for which the methods delegate to the visitor.
|
||||
//! - All other types, including generic containers like `Vec` and `Option`.
|
||||
//! It defines a "skeleton" of how they should be visited.
|
||||
//! - `TypeSuperVisitable`. This is implemented only for recursive types of
|
||||
//! interest, and defines the visiting "skeleton" for these types. (This
|
||||
//! excludes `Region` because it is non-recursive, i.e. it never contains
|
||||
//! other types of interest.)
|
||||
//! - `CustomizableTypeVisitor`. This is implemented for each visitor. This defines how
|
||||
//! types of interest are visited.
|
||||
//!
|
||||
//! This means each visit is a mixture of (a) generic visiting operations, and (b)
|
||||
//! custom visit operations that are specific to the visitor.
|
||||
//! - The `GenericTypeVisitable` impls handle most of the traversal, and call into
|
||||
//! `CustomizableTypeVisitor` when they encounter a type of interest.
|
||||
//! - A `CustomizableTypeVisitor` may call into another `GenericTypeVisitable` impl, because some of
|
||||
//! the types of interest are recursive and can contain other types of interest.
|
||||
//! - A `CustomizableTypeVisitor` may also call into a `TypeSuperVisitable` impl, because each
|
||||
//! visitor might provide custom handling only for some types of interest, or
|
||||
//! only for some variants of each type of interest, and then use default
|
||||
//! traversal for the remaining cases.
|
||||
//!
|
||||
//! For example, if you have `struct S(Ty, U)` where `S: GenericTypeVisitable` and `U:
|
||||
//! GenericTypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so:
|
||||
//! ```text
|
||||
//! s.generic_visit_with(visitor) calls
|
||||
//! - ty.generic_visit_with(visitor) calls
|
||||
//! - visitor.visit_ty(ty) may call
|
||||
//! - ty.super_generic_visit_with(visitor)
|
||||
//! - u.generic_visit_with(visitor)
|
||||
//! ```
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use smallvec::SmallVec;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
/// This trait is implemented for every type that can be visited,
|
||||
/// providing the skeleton of the traversal.
|
||||
///
|
||||
/// To implement this conveniently, use the derive macro located in
|
||||
/// `rustc_macros`.
|
||||
pub trait GenericTypeVisitable<V> {
|
||||
/// The entry point for visiting. To visit a value `t` with a visitor `v`
|
||||
/// call: `t.generic_visit_with(v)`.
|
||||
///
|
||||
/// For most types, this just traverses the value, calling `generic_visit_with` on
|
||||
/// each field/element.
|
||||
///
|
||||
/// For types of interest (such as `Ty`), the implementation of this method
|
||||
/// that calls a visitor method specifically for that type (such as
|
||||
/// `V::visit_ty`). This is where control transfers from `GenericTypeVisitable` to
|
||||
/// `CustomizableTypeVisitor`.
|
||||
fn generic_visit_with(&self, visitor: &mut V);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Traversal implementations.
|
||||
|
||||
impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for &T {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
T::generic_visit_with(*self, visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>, U: GenericTypeVisitable<V>> GenericTypeVisitable<V> for (T, U) {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.0.generic_visit_with(visitor);
|
||||
self.1.generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, A: GenericTypeVisitable<V>, B: GenericTypeVisitable<V>, C: GenericTypeVisitable<V>>
|
||||
GenericTypeVisitable<V> for (A, B, C)
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.0.generic_visit_with(visitor);
|
||||
self.1.generic_visit_with(visitor);
|
||||
self.2.generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Option<T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
match self {
|
||||
Some(v) => v.generic_visit_with(visitor),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>, E: GenericTypeVisitable<V>> GenericTypeVisitable<V>
|
||||
for Result<T, E>
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
match self {
|
||||
Ok(v) => v.generic_visit_with(visitor),
|
||||
Err(e) => e.generic_visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Arc<T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
(**self).generic_visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Box<T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
(**self).generic_visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Vec<T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for ThinVec<T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>, const N: usize> GenericTypeVisitable<V> for SmallVec<[T; N]> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for [T] {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>, Ix: Idx> GenericTypeVisitable<V> for IndexVec<Ix, T> {
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, V> GenericTypeVisitable<V> for std::hash::BuildHasherDefault<S> {
|
||||
fn generic_visit_with(&self, _visitor: &mut V) {}
|
||||
}
|
||||
|
||||
#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
|
||||
impl<
|
||||
Visitor,
|
||||
Key: GenericTypeVisitable<Visitor>,
|
||||
Value: GenericTypeVisitable<Visitor>,
|
||||
S: GenericTypeVisitable<Visitor>,
|
||||
> GenericTypeVisitable<Visitor> for std::collections::HashMap<Key, Value, S>
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut Visitor) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
self.hasher().generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
|
||||
impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
|
||||
for std::collections::HashSet<T, S>
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
self.hasher().generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
Visitor,
|
||||
Key: GenericTypeVisitable<Visitor>,
|
||||
Value: GenericTypeVisitable<Visitor>,
|
||||
S: GenericTypeVisitable<Visitor>,
|
||||
> GenericTypeVisitable<Visitor> for indexmap::IndexMap<Key, Value, S>
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut Visitor) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
self.hasher().generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
|
||||
for indexmap::IndexSet<T, S>
|
||||
{
|
||||
fn generic_visit_with(&self, visitor: &mut V) {
|
||||
self.iter().for_each(|it| it.generic_visit_with(visitor));
|
||||
self.hasher().generic_visit_with(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! trivial_impls {
|
||||
( $($ty:ty),* $(,)? ) => {
|
||||
$(
|
||||
impl<V>
|
||||
GenericTypeVisitable<V> for $ty
|
||||
{
|
||||
fn generic_visit_with(&self, _visitor: &mut V) {}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
trivial_impls!(
|
||||
(),
|
||||
rustc_ast_ir::Mutability,
|
||||
bool,
|
||||
i8,
|
||||
i16,
|
||||
i32,
|
||||
i64,
|
||||
i128,
|
||||
isize,
|
||||
u8,
|
||||
u16,
|
||||
u32,
|
||||
u64,
|
||||
u128,
|
||||
usize,
|
||||
crate::PredicatePolarity,
|
||||
crate::BoundConstness,
|
||||
crate::AliasRelationDirection,
|
||||
crate::DebruijnIndex,
|
||||
crate::solve::Certainty,
|
||||
crate::UniverseIndex,
|
||||
crate::BoundVar,
|
||||
crate::InferTy,
|
||||
crate::IntTy,
|
||||
crate::UintTy,
|
||||
crate::FloatTy,
|
||||
crate::InferConst,
|
||||
crate::RegionVid,
|
||||
rustc_hash::FxBuildHasher,
|
||||
crate::TypeFlags,
|
||||
crate::solve::GoalSource,
|
||||
);
|
||||
|
|
@ -44,6 +44,8 @@ mod const_kind;
|
|||
mod flags;
|
||||
mod fold;
|
||||
mod generic_arg;
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
mod generic_visit;
|
||||
mod infer_ctxt;
|
||||
mod interner;
|
||||
mod opaque_ty;
|
||||
|
|
@ -67,6 +69,8 @@ pub use const_kind::*;
|
|||
pub use flags::*;
|
||||
pub use fold::*;
|
||||
pub use generic_arg::*;
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
pub use generic_visit::*;
|
||||
pub use infer_ctxt::*;
|
||||
pub use interner::*;
|
||||
pub use opaque_ty::*;
|
||||
|
|
@ -75,6 +79,7 @@ pub use predicate::*;
|
|||
pub use predicate_kind::*;
|
||||
pub use region_kind::*;
|
||||
pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
|
||||
use rustc_type_ir_macros::GenericTypeVisitable;
|
||||
pub use ty_info::*;
|
||||
pub use ty_kind::*;
|
||||
pub use upcast::*;
|
||||
|
|
@ -213,7 +218,7 @@ pub fn debug_bound_var<T: std::fmt::Write>(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, GenericTypeVisitable)]
|
||||
#[cfg_attr(feature = "nightly", derive(Decodable, Encodable, HashStable_NoContext))]
|
||||
#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
|
||||
pub enum Variance {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::inherent::*;
|
||||
use crate::{self as ty, Interner};
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::Interner;
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ use derive_where::derive_where;
|
|||
use rustc_macros::{
|
||||
Decodable, Decodable_NoContext, Encodable, Encodable_NoContext, HashStable_NoContext,
|
||||
};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::inherent::*;
|
||||
use crate::lift::Lift;
|
||||
|
|
@ -17,7 +19,7 @@ use crate::{self as ty, Interner};
|
|||
/// `A: 'region`
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)]
|
||||
#[derive_where(Copy; I: Interner, A: Copy)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -52,7 +54,7 @@ where
|
|||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the generic parameters.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -129,7 +131,7 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -274,7 +276,7 @@ impl fmt::Display for PredicatePolarity {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -325,7 +327,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
|
|||
/// The generic parameters don't include the erased `Self`, only trait
|
||||
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -394,7 +396,7 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
|
|||
|
||||
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -552,7 +554,7 @@ impl From<ty::AliasTyKind> for AliasTermKind {
|
|||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||
/// * For an opaque type, there is no explicit syntax.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -764,7 +766,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
|
|||
/// Form #2 eventually yields one of these `ProjectionPredicate`
|
||||
/// instances to normalize the LHS.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -827,7 +829,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
|
|||
/// Used by the new solver to normalize an alias. This always expects the `term` to
|
||||
/// be an unconstrained inference variable which is used as the output.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -864,7 +866,7 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -910,7 +912,7 @@ impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
|
|||
/// whether the `a` type is the type that we should label as "expected" when
|
||||
/// presenting user diagnostics.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -925,7 +927,7 @@ impl<I: Interner> Eq for SubtypePredicate<I> {}
|
|||
|
||||
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use std::fmt;
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::{self as ty, Interner};
|
||||
|
||||
/// A clause is something that can appear in where bounds or be inferred
|
||||
/// by implied bounds.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -58,7 +58,7 @@ pub enum ClauseKind<I: Interner> {
|
|||
impl<I: Interner> Eq for ClauseKind<I> {}
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use derive_where::derive_where;
|
|||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::GenericTypeVisitable;
|
||||
|
||||
use self::RegionKind::*;
|
||||
use crate::{BoundVarIndexKind, Interner};
|
||||
|
|
@ -126,6 +127,7 @@ rustc_index::newtype_index! {
|
|||
/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
|
||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
|
||||
pub enum RegionKind<I: Interner> {
|
||||
/// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
//! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::solve::{CandidateSource, Certainty, Goal, GoalSource, QueryResult};
|
||||
use crate::{Canonical, CanonicalVarValues, Interner};
|
||||
|
|
@ -31,7 +31,7 @@ use crate::{Canonical, CanonicalVarValues, Interner};
|
|||
/// inference variables from a nested `InferCtxt`.
|
||||
#[derive_where(Clone, PartialEq, Hash, Debug; I: Interner, T)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub struct State<I: Interner, T> {
|
||||
pub var_values: CanonicalVarValues<I>,
|
||||
pub data: T,
|
||||
|
|
@ -87,7 +87,7 @@ pub enum ProbeStep<I: Interner> {
|
|||
/// the final result of the current goal - via [ProbeKind::Root] - we also
|
||||
/// store the [QueryResult].
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub enum ProbeKind<I: Interner> {
|
||||
/// The root inference context while proving a goal.
|
||||
Root { result: QueryResult<I> },
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ use std::hash::Hash;
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::lang_items::SolverTraitLangItem;
|
||||
use crate::search_graph::PathKind;
|
||||
|
|
@ -33,7 +35,7 @@ pub struct NoSolution;
|
|||
/// we're currently typechecking while the `predicate` is some trait bound.
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)]
|
||||
#[derive_where(Copy; I: Interner, P: Copy)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -95,7 +97,7 @@ pub enum GoalSource {
|
|||
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal<I, P>)]
|
||||
#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -206,7 +208,7 @@ pub enum ParamEnvSource {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub enum AliasBoundKind {
|
||||
/// Alias bound from the self type of a projection
|
||||
SelfBounds,
|
||||
|
|
@ -235,7 +237,7 @@ pub enum BuiltinImplSource {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct Response<I: Interner> {
|
||||
pub certainty: Certainty,
|
||||
|
|
@ -248,7 +250,7 @@ impl<I: Interner> Eq for Response<I> {}
|
|||
|
||||
/// Additional constraints returned on success.
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct ExternalConstraintsData<I: Interner> {
|
||||
pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>,
|
||||
|
|
@ -267,7 +269,7 @@ impl<I: Interner> ExternalConstraintsData<I> {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use std::ops::Deref;
|
|||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_type_ir_macros::GenericTypeVisitable;
|
||||
|
||||
use crate::{DebruijnIndex, TypeFlags};
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ use crate::{DebruijnIndex, TypeFlags};
|
|||
/// StableHash::ZERO for the hash, in which case the hash gets computed each time.
|
||||
/// This is useful if you have values that you intern but never (can?) use for stable
|
||||
/// hashing.
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, GenericTypeVisitable)]
|
||||
pub struct WithCachedTypeInfo<T> {
|
||||
pub internee: T,
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
|||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir::data_structures::{NoError, UnifyKey, UnifyValue};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use self::TyKind::*;
|
||||
pub use self::closure::*;
|
||||
|
|
@ -20,6 +22,7 @@ use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy};
|
|||
mod closure;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -56,6 +59,7 @@ impl AliasTyKind {
|
|||
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
|
||||
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
#[derive(GenericTypeVisitable)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -391,7 +395,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
|
|||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||
/// * For an opaque type, there is no explicit syntax.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -713,7 +717,7 @@ impl fmt::Debug for InferTy {
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub struct TypeAndMut<I: Interner> {
|
||||
pub ty: I::Ty,
|
||||
pub mutbl: Mutability,
|
||||
|
|
@ -726,7 +730,7 @@ impl<I: Interner> Eq for TypeAndMut<I> {}
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSig<I: Interner> {
|
||||
pub inputs_and_output: I::Tys,
|
||||
pub c_variadic: bool,
|
||||
|
|
@ -839,7 +843,7 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
|
|||
// impls in this crate for `Binder<I, I::Ty>`.
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
|
||||
|
||||
impl<I: Interner> Eq for UnsafeBinderInner<I> {}
|
||||
|
|
@ -905,7 +909,7 @@ where
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSigTys<I: Interner> {
|
||||
pub inputs_and_output: I::Tys,
|
||||
}
|
||||
|
|
@ -959,7 +963,7 @@ impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnHeader<I: Interner> {
|
||||
pub c_variadic: bool,
|
||||
pub safety: I::Safety,
|
||||
|
|
@ -973,7 +977,7 @@ impl<I: Interner> Eq for FnHeader<I> {}
|
|||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CoroutineWitnessTypes<I: Interner> {
|
||||
pub types: I::Tys,
|
||||
pub assumptions: I::RegionAssumptions,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use rustc_type_ir_macros::{
|
||||
GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
|
||||
};
|
||||
|
||||
use crate::data_structures::DelayedMap;
|
||||
use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region};
|
||||
|
|
@ -102,7 +104,7 @@ use crate::{self as ty, Interner};
|
|||
/// * `GR`: The "return type", which is the type of value returned upon
|
||||
/// completion of the coroutine.
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct ClosureArgs<I: Interner> {
|
||||
/// Lifetime and type parameters from the enclosing function,
|
||||
/// concatenated with a tuple containing the types of the upvars.
|
||||
|
|
@ -206,7 +208,7 @@ impl<I: Interner> ClosureArgs<I> {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CoroutineClosureArgs<I: Interner> {
|
||||
pub args: I::GenericArgs,
|
||||
}
|
||||
|
|
@ -354,7 +356,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub struct CoroutineClosureSignature<I: Interner> {
|
||||
pub tupled_inputs_ty: I::Ty,
|
||||
pub resume_ty: I::Ty,
|
||||
|
|
@ -549,7 +551,7 @@ impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
|
|||
}
|
||||
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
|
||||
pub struct GenSig<I: Interner> {
|
||||
pub resume_ty: I::Ty,
|
||||
pub yield_ty: I::Ty,
|
||||
|
|
@ -559,7 +561,7 @@ pub struct GenSig<I: Interner> {
|
|||
impl<I: Interner> Eq for GenSig<I> {}
|
||||
/// Similar to `ClosureArgs`; see the above documentation for more.
|
||||
#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CoroutineArgs<I: Interner> {
|
||||
pub args: I::GenericArgs,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ edition = "2024"
|
|||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[features]
|
||||
nightly = []
|
||||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
proc-macro2 = "1"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ decl_derive!(
|
|||
decl_derive!(
|
||||
[Lift_Generic] => lift_derive
|
||||
);
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
decl_derive!(
|
||||
[GenericTypeVisitable] => customizable_type_visitable_derive
|
||||
);
|
||||
|
||||
fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool {
|
||||
let mut ignored = false;
|
||||
|
|
@ -211,3 +215,39 @@ fn lift(mut ty: syn::Type) -> syn::Type {
|
|||
|
||||
ty
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
fn customizable_type_visitable_derive(
|
||||
mut s: synstructure::Structure<'_>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
if let syn::Data::Union(_) = s.ast().data {
|
||||
panic!("cannot derive on union")
|
||||
}
|
||||
|
||||
s.add_impl_generic(parse_quote!(__V));
|
||||
s.add_bounds(synstructure::AddBounds::Fields);
|
||||
let body_visit = s.each(|bind| {
|
||||
quote! {
|
||||
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(#bind, __visitor);
|
||||
}
|
||||
});
|
||||
s.bind_with(|_| synstructure::BindStyle::Move);
|
||||
|
||||
s.bound_impl(
|
||||
quote!(::rustc_type_ir::GenericTypeVisitable<__V>),
|
||||
quote! {
|
||||
fn generic_visit_with(
|
||||
&self,
|
||||
__visitor: &mut __V
|
||||
) {
|
||||
match *self { #body_visit }
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
#[proc_macro_derive(GenericTypeVisitable)]
|
||||
pub fn customizable_type_visitable_derive(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
proc_macro::TokenStream::new()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@
|
|||
//! * [`Sender`]
|
||||
//! * [`Receiver`]
|
||||
//!
|
||||
//! [`Sender`]s are used to send data to a set of [`Receiver`]s. Both
|
||||
//! sender and receiver are cloneable (multi-producer) such that many threads can send
|
||||
//! simultaneously to receivers (multi-consumer).
|
||||
//! [`Sender`]s are used to send data to a set of [`Receiver`]s where each item
|
||||
//! sent is delivered to (at most) one receiver. Both sender and receiver are
|
||||
//! cloneable (multi-producer) such that many threads can send simultaneously
|
||||
//! to receivers (multi-consumer).
|
||||
//!
|
||||
//! These channels come in two flavors:
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use crate::path::{Path, PathBuf};
|
|||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{helpers, unsupported};
|
||||
|
||||
#[expect(dead_code)]
|
||||
const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY;
|
||||
|
||||
pub struct File(!);
|
||||
|
|
@ -109,7 +108,6 @@ impl FilePermissions {
|
|||
Self(attr & r_efi::protocols::file::READ_ONLY != 0)
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
const fn to_attr(&self) -> u64 {
|
||||
if self.0 { r_efi::protocols::file::READ_ONLY } else { 0 }
|
||||
}
|
||||
|
|
@ -366,16 +364,40 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
|
|||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
|
||||
unsupported()
|
||||
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
|
||||
let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?;
|
||||
let mut file_info = f.file_info()?;
|
||||
|
||||
unsafe {
|
||||
(*file_info.as_mut_ptr()).attribute =
|
||||
((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr()
|
||||
};
|
||||
|
||||
f.set_file_info(file_info)
|
||||
}
|
||||
|
||||
pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> {
|
||||
unsupported()
|
||||
pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
|
||||
// UEFI does not support symlinks
|
||||
set_times_nofollow(p, times)
|
||||
}
|
||||
|
||||
pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> {
|
||||
unsupported()
|
||||
pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> {
|
||||
let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?;
|
||||
let mut file_info = f.file_info()?;
|
||||
|
||||
if let Some(x) = times.accessed {
|
||||
unsafe {
|
||||
(*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(x) = times.modified {
|
||||
unsafe {
|
||||
(*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x);
|
||||
}
|
||||
}
|
||||
|
||||
f.set_file_info(file_info)
|
||||
}
|
||||
|
||||
pub fn rmdir(p: &Path) -> io::Result<()> {
|
||||
|
|
@ -560,6 +582,17 @@ mod uefi_fs {
|
|||
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(info) }
|
||||
}
|
||||
|
||||
pub(crate) fn set_file_info(&self, mut info: UefiBox<file::Info>) -> io::Result<()> {
|
||||
let file_ptr = self.0.as_ptr();
|
||||
let mut info_id = file::INFO_ID;
|
||||
|
||||
let r = unsafe {
|
||||
((*file_ptr).set_info)(file_ptr, &mut info_id, info.len(), info.as_mut_ptr().cast())
|
||||
};
|
||||
|
||||
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
|
||||
}
|
||||
|
||||
pub(crate) fn delete(self) -> io::Result<()> {
|
||||
let file_ptr = self.0.as_ptr();
|
||||
let r = unsafe { ((*file_ptr).delete)(file_ptr) };
|
||||
|
|
@ -643,8 +676,7 @@ mod uefi_fs {
|
|||
}
|
||||
|
||||
/// Convert to UEFI Time with the current timezone.
|
||||
#[expect(dead_code)]
|
||||
fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time {
|
||||
pub(crate) fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time {
|
||||
let now = time::system_time_internal::now();
|
||||
time.to_uefi_loose(now.timezone, now.daylight)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -802,6 +802,10 @@ impl<T> UefiBox<T> {
|
|||
pub(crate) fn as_ptr(&self) -> *const T {
|
||||
self.inner.as_ptr().cast()
|
||||
}
|
||||
|
||||
pub(crate) const fn len(&self) -> usize {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for UefiBox<T> {
|
||||
|
|
|
|||
|
|
@ -221,7 +221,10 @@ please file issues on the [Rust issue tracker][rust-issue-tracker].
|
|||
|
||||
## Testing
|
||||
|
||||
To run bootstrap tests, execute `x test bootstrap`. If you want to bless snapshot tests, then install `cargo-insta` (`cargo install cargo-insta`) and then run `cargo insta review --manifest-path src/bootstrap/Cargo.toml`.
|
||||
To run bootstrap tests, execute `x test bootstrap`.
|
||||
If you want to bless snapshot tests,
|
||||
then install `cargo-insta` (`cargo install cargo-insta`),
|
||||
and then run `cargo insta review --manifest-path src/bootstrap/Cargo.toml`.
|
||||
|
||||
## Changelog
|
||||
|
||||
|
|
|
|||
|
|
@ -1232,19 +1232,6 @@ pub fn rustc_cargo(
|
|||
// <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Internal.20lint.20for.20raw.20.60print!.60.20and.20.60println!.60.3F>.
|
||||
cargo.rustflag("-Zon-broken-pipe=kill");
|
||||
|
||||
// We want to link against registerEnzyme and in the future we want to use additional
|
||||
// functionality from Enzyme core. For that we need to link against Enzyme.
|
||||
if builder.config.llvm_enzyme {
|
||||
let arch = builder.build.host_target;
|
||||
let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib");
|
||||
cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path"));
|
||||
|
||||
if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
|
||||
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
|
||||
cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}"));
|
||||
}
|
||||
}
|
||||
|
||||
// Building with protected visibility reduces the number of dynamic relocations needed, giving
|
||||
// us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
|
||||
// with direct references to protected symbols, so for now we only use protected symbols if
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
|
|||
"sparc64-unknown-helenos",
|
||||
// just a dummy comment so the list doesn't get onelined
|
||||
"riscv64gc-unknown-redox",
|
||||
"riscv64im-unknown-none-elf",
|
||||
"hexagon-unknown-qurt",
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 9fe8fa599ad228dda74f240cc32b54bc5c1aa3e6
|
||||
Subproject commit 5b3a9d084cbc64e54da87e3eec7c7faae0e48ba9
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 50c5de90487b68d429a30cc9466dc8f5b410128f
|
||||
Subproject commit ec78de0ffe2f8344bd0e222b17ac7a7d32dc7a26
|
||||
|
|
@ -112,6 +112,7 @@
|
|||
- [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
|
||||
- [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md)
|
||||
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
|
||||
- [riscv64im-unknown-none-elf](platform-support/riscv64im-unknown-none-elf.md)
|
||||
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
|
||||
- [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
|
||||
- [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md)
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ target | std | notes
|
|||
[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA)
|
||||
[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5)
|
||||
`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
|
||||
[`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA)
|
||||
`riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
|
||||
`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23)
|
||||
[`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# `riscv64im-unknown-none-elf`
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Bare-metal target for RISC-V CPUs with the RV64IM ISA.
|
||||
|
||||
## Target maintainers
|
||||
|
||||
* Rust Embedded Working Group, [RISC-V team](https://github.com/rust-embedded/wg#the-risc-v-team)
|
||||
|
||||
## Requirements
|
||||
|
||||
This target is cross-compiled and uses static linking. The target supports `core` and `alloc`, but not `std`.
|
||||
|
||||
As the RV64IM ISA lacks the "A" (Atomics) extension, atomic operations are emulated using the `+forced-atomics` feature.
|
||||
|
||||
No external toolchain is required and the default `rust-lld` linker works, but you must specify a linker script. The [`riscv-rt`] crate provides suitable linker scripts. The [`riscv-rust-quickstart`] repository gives examples of RISC-V bare-metal projects.
|
||||
|
||||
[`riscv-rt`]: https://crates.io/crates/riscv-rt
|
||||
[`riscv-rust-quickstart`]: https://github.com/riscv-rust/riscv-rust-quickstart
|
||||
|
||||
## Building the target
|
||||
|
||||
You can build Rust with support for the target by adding it to the `target` list in `bootstrap.toml`:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["riscv64im-unknown-none-elf"]
|
||||
```
|
||||
|
||||
Alternatively, you can use the `-Z build-std` flag to build the standard library on-demand:
|
||||
|
||||
```bash
|
||||
cargo build -Z build-std=core,alloc --target riscv64im-unknown-none-elf
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for this target. To compile for this target (see "Building the target" above)
|
||||
|
||||
## Testing
|
||||
|
||||
This is a cross-compiled `no-std` target, which must be run either in a simulator or by programming onto suitable hardware. It is not possible to run the Rust test-suite on this target.
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`.
|
||||
|
|
@ -520,6 +520,9 @@
|
|||
//@ revisions: riscv64gc_unknown_redox
|
||||
//@ [riscv64gc_unknown_redox] compile-flags: --target riscv64gc-unknown-redox
|
||||
//@ [riscv64gc_unknown_redox] needs-llvm-components: riscv
|
||||
//@ revisions: riscv64im_unknown_none_elf
|
||||
//@ [riscv64im_unknown_none_elf] compile-flags: --target riscv64im-unknown-none-elf
|
||||
//@ [riscv64im_unknown_none_elf] needs-llvm-components: riscv
|
||||
//@ revisions: riscv64imac_unknown_none_elf
|
||||
//@ [riscv64imac_unknown_none_elf] compile-flags: --target riscv64imac-unknown-none-elf
|
||||
//@ [riscv64imac_unknown_none_elf] needs-llvm-components: riscv
|
||||
|
|
|
|||
24
tests/ui/attributes/codegen_attr_on_required_trait_method.rs
Normal file
24
tests/ui/attributes/codegen_attr_on_required_trait_method.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#![deny(unused_attributes)]
|
||||
#![feature(linkage)]
|
||||
#![feature(fn_align)]
|
||||
|
||||
trait Test {
|
||||
#[cold]
|
||||
//~^ ERROR cannot be used on required trait methods [unused_attributes]
|
||||
//~| WARN previously accepted
|
||||
fn method1(&self);
|
||||
#[link_section = ".text"]
|
||||
//~^ ERROR cannot be used on required trait methods [unused_attributes]
|
||||
//~| WARN previously accepted
|
||||
fn method2(&self);
|
||||
#[linkage = "common"]
|
||||
//~^ ERROR cannot be used on required trait methods [unused_attributes]
|
||||
//~| WARN previously accepted
|
||||
fn method3(&self);
|
||||
#[track_caller]
|
||||
fn method4(&self);
|
||||
#[rustc_align(1)]
|
||||
fn method5(&self);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
error: `#[cold]` attribute cannot be used on required trait methods
|
||||
--> $DIR/codegen_attr_on_required_trait_method.rs:6:5
|
||||
|
|
||||
LL | #[cold]
|
||||
| ^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[cold]` can be applied to closures, foreign functions, functions, inherent methods, provided trait methods, and trait methods in impl blocks
|
||||
note: the lint level is defined here
|
||||
--> $DIR/codegen_attr_on_required_trait_method.rs:1:9
|
||||
|
|
||||
LL | #![deny(unused_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[link_section]` attribute cannot be used on required trait methods
|
||||
--> $DIR/codegen_attr_on_required_trait_method.rs:10:5
|
||||
|
|
||||
LL | #[link_section = ".text"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
|
||||
|
||||
error: `#[linkage]` attribute cannot be used on required trait methods
|
||||
--> $DIR/codegen_attr_on_required_trait_method.rs:14:5
|
||||
|
|
||||
LL | #[linkage = "common"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[linkage]` can be applied to foreign functions, foreign statics, functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
@ -680,6 +680,10 @@ mod link_section {
|
|||
//~| HELP remove the attribute
|
||||
trait Tr {
|
||||
#[link_section = "1800"]
|
||||
//~^ WARN attribute cannot be used on
|
||||
//~| WARN previously accepted
|
||||
//~| HELP can be applied to
|
||||
//~| HELP remove the attribute
|
||||
fn inside_tr_no_default(&self);
|
||||
|
||||
#[link_section = "1800"]
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ LL | #![reexport_test_harness_main = "2900"]
|
|||
| +
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:1
|
||||
|
|
||||
LL | #[link(name = "x")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -219,7 +219,7 @@ LL | | }
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:832:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:1
|
||||
|
|
||||
LL | #[crate_type = "0800"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -230,7 +230,7 @@ LL | #![crate_type = "0800"]
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:856:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1
|
||||
|
|
||||
LL | #[feature(x0600)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -241,7 +241,7 @@ LL | #![feature(x0600)]
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:881:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1
|
||||
|
|
||||
LL | #[no_main]
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -252,7 +252,7 @@ LL | #![no_main]
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:905:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:1
|
||||
|
|
||||
LL | #[no_builtins]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -329,7 +329,7 @@ LL | #![reexport_test_harness_main = "2900"] impl S { }
|
|||
| +
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17
|
||||
|
|
||||
LL | mod inner { #![link(name = "x")] }
|
||||
| ------------^^^^^^^^^^^^^^^^^^^^-- not an `extern` block
|
||||
|
|
@ -337,7 +337,7 @@ LL | mod inner { #![link(name = "x")] }
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
|
||||
|
|
||||
LL | #[link(name = "x")] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block
|
||||
|
|
@ -345,7 +345,7 @@ LL | #[link(name = "x")] fn f() { }
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5
|
||||
|
|
||||
LL | #[link(name = "x")] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^ --------- not an `extern` block
|
||||
|
|
@ -353,7 +353,7 @@ LL | #[link(name = "x")] struct S;
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5
|
||||
|
|
||||
LL | #[link(name = "x")] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^ ----------- not an `extern` block
|
||||
|
|
@ -361,7 +361,7 @@ LL | #[link(name = "x")] type T = S;
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5
|
||||
|
|
||||
LL | #[link(name = "x")] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block
|
||||
|
|
@ -369,7 +369,7 @@ LL | #[link(name = "x")] impl S { }
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:5
|
||||
|
|
||||
LL | #[link(name = "x")] extern "Rust" {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -377,13 +377,13 @@ LL | #[link(name = "x")] extern "Rust" {}
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: crate-level attribute should be in the root module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:840:17
|
||||
|
|
||||
LL | mod inner { #![crate_type="0800"] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
|
||||
|
|
||||
LL | #[crate_type = "0800"] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -394,7 +394,7 @@ LL | #![crate_type = "0800"] fn f() { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
|
||||
|
|
||||
LL | #[crate_type = "0800"] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -405,7 +405,7 @@ LL | #![crate_type = "0800"] struct S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5
|
||||
|
|
||||
LL | #[crate_type = "0800"] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -416,7 +416,7 @@ LL | #![crate_type = "0800"] type T = S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5
|
||||
|
|
||||
LL | #[crate_type = "0800"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -427,13 +427,13 @@ LL | #![crate_type = "0800"] impl S { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be in the root module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:864:17
|
||||
|
|
||||
LL | mod inner { #![feature(x0600)] }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:863:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5
|
||||
|
|
||||
LL | #[feature(x0600)] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -444,7 +444,7 @@ LL | #![feature(x0600)] fn f() { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5
|
||||
|
|
||||
LL | #[feature(x0600)] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -455,7 +455,7 @@ LL | #![feature(x0600)] struct S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5
|
||||
|
|
||||
LL | #[feature(x0600)] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -466,7 +466,7 @@ LL | #![feature(x0600)] type T = S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:879:5
|
||||
|
|
||||
LL | #[feature(x0600)] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -477,13 +477,13 @@ LL | #![feature(x0600)] impl S { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be in the root module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17
|
||||
|
|
||||
LL | mod inner { #![no_main] }
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:888:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5
|
||||
|
|
||||
LL | #[no_main] fn f() { }
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -494,7 +494,7 @@ LL | #![no_main] fn f() { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5
|
||||
|
|
||||
LL | #[no_main] struct S;
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -505,7 +505,7 @@ LL | #![no_main] struct S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5
|
||||
|
|
||||
LL | #[no_main] type T = S;
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -516,7 +516,7 @@ LL | #![no_main] type T = S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5
|
||||
|
|
||||
LL | #[no_main] impl S { }
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -527,13 +527,13 @@ LL | #![no_main] impl S { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be in the root module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:913:17
|
||||
|
|
||||
LL | mod inner { #![no_builtins] }
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:912:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5
|
||||
|
|
||||
LL | #[no_builtins] fn f() { }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -544,7 +544,7 @@ LL | #![no_builtins] fn f() { }
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5
|
||||
|
|
||||
LL | #[no_builtins] struct S;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -555,7 +555,7 @@ LL | #![no_builtins] struct S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5
|
||||
|
|
||||
LL | #[no_builtins] type T = S;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -566,7 +566,7 @@ LL | #![no_builtins] type T = S;
|
|||
| +
|
||||
|
||||
warning: crate-level attribute should be an inner attribute
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:928:5
|
||||
|
|
||||
LL | #[no_builtins] impl S { }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -1222,8 +1222,17 @@ LL | #[link_section = "1800"]
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[link_section]` can be applied to functions and statics
|
||||
|
||||
warning: `#[link_section]` attribute cannot be used on required trait methods
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:9
|
||||
|
|
||||
LL | #[link_section = "1800"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
|
||||
|
||||
warning: `#[must_use]` attribute cannot be used on modules
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:1
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -1232,7 +1241,7 @@ LL | #[must_use]
|
|||
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
|
||||
|
||||
warning: `#[must_use]` attribute cannot be used on modules
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:17
|
||||
|
|
||||
LL | mod inner { #![must_use] }
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -1241,7 +1250,7 @@ LL | mod inner { #![must_use] }
|
|||
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
|
||||
|
||||
warning: `#[must_use]` attribute cannot be used on type aliases
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:771:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:775:5
|
||||
|
|
||||
LL | #[must_use] type T = S;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -1250,7 +1259,7 @@ LL | #[must_use] type T = S;
|
|||
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
|
||||
|
||||
warning: `#[must_use]` attribute cannot be used on inherent impl blocks
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
|
||||
|
|
||||
LL | #[must_use] impl S { }
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -1259,13 +1268,13 @@ LL | #[must_use] impl S { }
|
|||
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1
|
||||
|
|
||||
LL | / mod windows_subsystem {
|
||||
LL | |
|
||||
|
|
@ -1275,67 +1284,67 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
warning: the `#![windows_subsystem]` attribute can only be used at the crate root
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17
|
||||
|
|
||||
LL | mod inner { #![windows_subsystem="windows"] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this function
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:38
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] fn f() { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this struct
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] struct S;
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this type alias
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] type T = S;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:5
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this implementation block
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:38
|
||||
|
|
||||
LL | #[windows_subsystem = "windows"] impl S { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:1
|
||||
|
|
||||
LL | #[crate_name = "0900"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:1
|
||||
|
|
||||
LL | / mod crate_name {
|
||||
LL | |
|
||||
|
|
@ -1345,67 +1354,67 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
warning: the `#![crate_name]` attribute can only be used at the crate root
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:816:17
|
||||
|
|
||||
LL | mod inner { #![crate_name="0900"] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5
|
||||
|
|
||||
LL | #[crate_name = "0900"] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this function
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:28
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28
|
||||
|
|
||||
LL | #[crate_name = "0900"] fn f() { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5
|
||||
|
|
||||
LL | #[crate_name = "0900"] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this struct
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28
|
||||
|
|
||||
LL | #[crate_name = "0900"] struct S;
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5
|
||||
|
|
||||
LL | #[crate_name = "0900"] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this type alias
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28
|
||||
|
|
||||
LL | #[crate_name = "0900"] type T = S;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5
|
||||
|
|
||||
LL | #[crate_name = "0900"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this implementation block
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:28
|
||||
|
|
||||
LL | #[crate_name = "0900"] impl S { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:1
|
||||
|
|
||||
LL | #[recursion_limit="0200"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:931:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:935:1
|
||||
|
|
||||
LL | / mod recursion_limit {
|
||||
LL | |
|
||||
|
|
@ -1415,67 +1424,67 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
warning: the `#![recursion_limit]` attribute can only be used at the crate root
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:17
|
||||
|
|
||||
LL | mod inner { #![recursion_limit="0200"] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5
|
||||
|
|
||||
LL | #[recursion_limit="0200"] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this function
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:31
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31
|
||||
|
|
||||
LL | #[recursion_limit="0200"] fn f() { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5
|
||||
|
|
||||
LL | #[recursion_limit="0200"] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this struct
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31
|
||||
|
|
||||
LL | #[recursion_limit="0200"] struct S;
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5
|
||||
|
|
||||
LL | #[recursion_limit="0200"] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this type alias
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31
|
||||
|
|
||||
LL | #[recursion_limit="0200"] type T = S;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:5
|
||||
|
|
||||
LL | #[recursion_limit="0200"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this implementation block
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:31
|
||||
|
|
||||
LL | #[recursion_limit="0200"] impl S { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:1
|
||||
|
|
||||
LL | #[type_length_limit="0100"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:955:1
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:959:1
|
||||
|
|
||||
LL | / mod type_length_limit {
|
||||
LL | |
|
||||
|
|
@ -1485,55 +1494,55 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
warning: the `#![type_length_limit]` attribute can only be used at the crate root
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:17
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:17
|
||||
|
|
||||
LL | mod inner { #![type_length_limit="0100"] }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5
|
||||
|
|
||||
LL | #[type_length_limit="0100"] fn f() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this function
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:33
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33
|
||||
|
|
||||
LL | #[type_length_limit="0100"] fn f() { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5
|
||||
|
|
||||
LL | #[type_length_limit="0100"] struct S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this struct
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33
|
||||
|
|
||||
LL | #[type_length_limit="0100"] struct S;
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5
|
||||
|
|
||||
LL | #[type_length_limit="0100"] type T = S;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this type alias
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33
|
||||
|
|
||||
LL | #[type_length_limit="0100"] type T = S;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:5
|
||||
|
|
||||
LL | #[type_length_limit="0100"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: This attribute does not have an `!`, which means it is applied to this implementation block
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:33
|
||||
|
|
||||
LL | #[type_length_limit="0100"] impl S { }
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -1601,5 +1610,5 @@ LL | #![must_use]
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
|
||||
|
||||
warning: 174 warnings emitted
|
||||
warning: 175 warnings emitted
|
||||
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ exclude_labels = [
|
|||
"T-infra",
|
||||
"T-release",
|
||||
"requires-nightly",
|
||||
"F-*",
|
||||
]
|
||||
|
||||
[autolabel."T-rustdoc"]
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ unstalled = "unstalled"
|
|||
debug_aranges = "debug_aranges"
|
||||
DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME = "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME"
|
||||
EnzymeTypeTreeShiftIndiciesEq = "EnzymeTypeTreeShiftIndiciesEq"
|
||||
EnzymeTypeTreeShiftIndiciesEqFn = "EnzymeTypeTreeShiftIndiciesEqFn"
|
||||
shift_indicies_eq = "shift_indicies_eq"
|
||||
ERRNO_ACCES = "ERRNO_ACCES"
|
||||
ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS"
|
||||
ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue