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:
bors 2025-12-16 06:27:13 +00:00
commit 6e7dd2cd99
64 changed files with 1295 additions and 496 deletions

View file

@ -3613,6 +3613,7 @@ dependencies = [
"gimli 0.31.1",
"itertools",
"libc",
"libloading 0.9.0",
"measureme",
"object 0.37.3",
"rustc-demangle",

View file

@ -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)),
]);

View file

@ -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),

View file

@ -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: [

View file

@ -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),
]);

View file

@ -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),

View file

@ -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

View file

@ -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);
}

View file

@ -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,

View file

@ -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()
}
});
}

View file

@ -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) {

View file

@ -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)
}
}

View file

@ -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,

View file

@ -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());
}
}

View file

@ -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));

View file

@ -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),

View file

@ -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;

View file

@ -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) \

View file

@ -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()
}
}

View file

@ -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
);

View file

@ -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 {

View file

@ -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;
}
}
}

View file

@ -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)

View file

@ -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,
}
}
}

View file

@ -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),

View file

@ -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()
},
}
}

View file

@ -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",
]

View file

@ -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,

View file

@ -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,
}

View file

@ -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)

View file

@ -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,

View file

@ -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)

View 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,
);

View file

@ -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 {

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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 ()`.

View file

@ -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> },

View file

@ -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>)>);

View file

@ -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,

View file

@ -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,

View file

@ -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,
}

View file

@ -6,6 +6,9 @@ edition = "2024"
[lib]
proc-macro = true
[features]
nightly = []
[dependencies]
# tidy-alphabetical-start
proc-macro2 = "1"

View file

@ -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()
}

View file

@ -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:
//!

View file

@ -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)
}

View file

@ -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> {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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`.

View file

@ -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

View 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() {}

View file

@ -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

View file

@ -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"]

View file

@ -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

View file

@ -229,6 +229,7 @@ exclude_labels = [
"T-infra",
"T-release",
"requires-nightly",
"F-*",
]
[autolabel."T-rustdoc"]

View file

@ -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"