Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4430,6 +4430,7 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr_ir",
"rustc_crate_store",
"rustc_data_structures",
"rustc_errors",
Expand Down
72 changes: 45 additions & 27 deletions compiler/rustc_attr_ir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Data structures for representing parsed attributes in the Rust compiler.
//!
//! For detailed documentation about attribute processing,
//! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html).
//! see [rustc_attr_parsing](../rustc_attr_parsing/index.html).

// tidy-alphabetical-start
#![feature(const_default)]
Expand All @@ -20,7 +20,6 @@ pub use lang_items::*;
pub use pretty_printing::PrintAttribute;
pub use stability::*;

// FIXME remove pub on some of these modules? It's fairly inconsistent.
mod attr;
mod canonical_symbols;
mod data_structures;
Expand All @@ -35,40 +34,38 @@ pub mod weak_lang_items;

/// A trait for types that can provide a list of attributes given a `TyCtxt`.
///
/// It allows `find_attr!` to accept either a `DefId`, `LocalDefId`, `OwnerId`, or `HirId`.
/// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`.
/// The concrete implementations are in `rustc_middle`.
/// It is an implementation detail of the [`find_attr!`] macro to be able to accept either a
/// [`DefId`], [`LocalDefId`], [`OwnerId`], or [`HirId`]. It is defined here with a generic `Tcx`
/// because this crate can't depend on `rustc_middle`. The concrete implementations are in
/// `rustc_middle`.
///
/// Not to be confused with [`rustc_ast::ast_traits::HasAttrs`].
///
/// [`DefId`]: rustc_span::def_id::DefId
/// [`LocalDefId`]: rustc_span::def_id::LocalDefId
/// [`OwnerId`]: ../rustc_hir/struct.OwnerId.html
/// [`HirId`]: ../rustc_hir/struct.HirId.html
pub trait HasAttrs<'tcx, Tcx> {
fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::attr::Attribute];
fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::Attribute];
}

/// Finds attributes in sequences of attributes by pattern matching.
/// Finds attributes by pattern matching.
///
/// A little like `matches` but for attributes.
///
/// ```rust,ignore (illustrative)
/// // finds the repr attribute
/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) {
///
/// }
///
/// // checks if one has matched
/// if find_attr!(attrs, AttributeKind::Repr(_)) {
///
/// }
/// ```
/// Note that this macro accepts several "id" types: [`DefId`], [`LocalDefId`], [`OwnerId`] and
/// [`HirId`].
///
/// Often this requires you to first end up with a list of attributes.
/// Often these are available through the `tcx`.
/// # Examples
///
/// As a convenience, this macro can do that for you!
/// It is most commonly used to check whether something has an attribute or to get its contents
/// if it is present:
/// ```rust,ignore (illustrative)
/// let is_naked: bool = find_attr!(tcx, def_id, Naked(..));
///
/// Instead of providing an attribute list, provide the `tcx` and an id
/// (a `DefId`, `LocalDefId`, `OwnerId` or `HirId`).
/// let is_visible: bool = find_attr!(tcx, def_id, Doc(doc) if doc.hidden.is_none());
///
/// ```rust,ignore (illustrative)
/// find_attr!(tcx, def_id, <pattern>)
/// find_attr!(tcx, hir_id, <pattern>)
/// let link_name: Option<Symbol> = find_attr!(tcx, def_id, LinkName { name, .. } => *name);
/// ```
///
/// Another common case is finding attributes applied to the root of the current crate.
Expand All @@ -77,6 +74,27 @@ pub trait HasAttrs<'tcx, Tcx> {
/// ```rust, ignore (illustrative)
/// find_attr!(tcx, crate, <pattern>)
/// ```
///
/// If you already have a list of attributes in scope, you can also use that:
///
/// ```rust,ignore (illustrative)
/// let attrs = <list of attributes>;
///
/// // finds the repr attribute
/// if let Some(r) = find_attr!(attrs, Repr(r) => r) {
///
/// }
///
/// // checks if one has matched
/// if find_attr!(attrs, Repr(_)) {
///
/// }
/// ```
///
/// [`DefId`]: rustc_span::def_id::DefId
/// [`LocalDefId`]: rustc_span::def_id::LocalDefId
/// [`OwnerId`]: ../rustc_hir/struct.OwnerId.html
/// [`HirId`]: ../rustc_hir/struct.HirId.html
#[macro_export]
macro_rules! find_attr {
($tcx: expr, crate, $pattern: pat $(if $guard: expr)?) => {
Expand All @@ -89,14 +107,14 @@ macro_rules! find_attr {
($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)?) => {
$crate::find_attr!($tcx, $id, $pattern $(if $guard)? => ()).is_some()
};

($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
$crate::find_attr!(
$crate::HasAttrs::get_attrs($id, &$tcx),
$pattern $(if $guard)? => $e
)
}};


($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
$crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ fn parse_directive_items<'p>(
WrappedParserError {
description: e.description,
label: e.label,
span: slice_span(input.span, e.span.clone(), is_snippet),
span: slice_span(input.span, e.span, is_snippet),
},
input.span,
);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub(crate) fn expand_option_env<'cx>(
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
};
let ExpandResult::Ready(mac) =
expr_to_string(cx, var_expr.clone(), "argument must be a string literal")
expr_to_string(cx, var_expr, "argument must be a string literal")
else {
return ExpandResult::Retry(());
};
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/src/offload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ pub(crate) fn expand_kernel(
// host function
let mut host_fn = Box::new(ast::Fn {
defaultness: ast::Defaultness::Implicit,
sig: sig.clone(),
sig,
ident,
generics: generics.clone(),
generics,
contract: None,
body: Some(body),
define_opaque: None,
Expand Down Expand Up @@ -176,7 +176,7 @@ pub(crate) fn expand_kernel(
thin_vec![rustc_offload_kernel, inline_never],
ast::ItemKind::Fn(host_fn),
);
item.vis = vis.clone();
item.vis = vis;
Annotatable::Item(item)
};

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/global_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> {
operands: &[GlobalAsmOperandRef<'tcx>],
options: InlineAsmOptions,
_line_spans: &[Span],
_target_features: &[String],
) {
codegen_global_asm_inner(self.tcx, self.global_asm, template, operands, options);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
operands: &[GlobalAsmOperandRef<'tcx>],
options: InlineAsmOptions,
line_spans: &[Span],
_target_features: &[String],
) {
let asm_arch = self.tcx.sess.asm_arch.unwrap();

Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
operands: &[GlobalAsmOperandRef<'tcx>],
options: InlineAsmOptions,
_line_spans: &[Span],
target_features: &[String],
) {
let asm_arch = self.tcx.sess.asm_arch.unwrap();

Expand Down Expand Up @@ -499,14 +500,11 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
template_str.push_str("\n.att_syntax\n");
}

let target_features = self.tcx.global_backend_features(()).join(",");
let target_cpu = llvm_util::target_cpu(self.tcx.sess);

llvm::append_module_inline_asm(
self.llmod,
template_str.as_bytes(),
&target_features,
target_cpu,
&target_features.join(","),
llvm_util::target_cpu(self.tcx.sess),
);
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,8 @@ unsafe extern "C" {
SLen: c_uint,
) -> MetadataKindId;

pub(crate) fn LLVMGetVersion(major: &mut c_uint, minor: &mut c_uint, patch: &mut c_uint);

pub(crate) fn LLVMDisposeTargetMachine(T: ptr::NonNull<TargetMachine>);

// Create modules.
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ unsafe fn configure_llvm(sess: &Session) {
let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
let mut llvm_args = Vec::with_capacity(n_args + 1);

// Check to ensure we're running against the correct LLVM version.
unsafe {
let mut llvm_major = 0;
let mut llvm_minor = 0;
let mut llvm_patch = 0;
llvm::LLVMGetVersion(&mut llvm_major, &mut llvm_minor, &mut llvm_patch);
let expected_version = llvm::LLVMRustVersionMajor();
if llvm_major != expected_version {
panic!(
concat!(
"LLVM version mismatch: this compiler was built for LLVM {}, ",
"but LLVM {}.{}.{} was found{}"
),
expected_version,
llvm_major,
llvm_minor,
llvm_patch,
match rustc_session::filesearch::dll_path(llvm::LLVMGetVersion as *mut _) {
Ok(path) => format!(" at {}", path.display()),
Err(_) => String::new(),
}
);
}
}

unsafe {
llvm::LLVMRustInstallErrorHandlers();
}
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,14 @@ where
})
.collect();

cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
let target_features = cx.tcx().global_backend_features(());
cx.codegen_global_asm(
asm.template,
&operands,
asm.options,
asm.line_spans,
&target_features,
);
} else {
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ pub fn codegen_naked_asm<
template_vec.extend(template.iter().cloned());
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end.into()));

cx.codegen_global_asm(&template_vec, &operands, options, line_spans);
let target_features: Vec<_> =
cx.tcx().asm_target_features(instance.def_id()).iter().map(|s| format!("+{s}")).collect();
cx.codegen_global_asm(&template_vec, &operands, options, line_spans, &target_features);
}

fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>>(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/traits/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub trait AsmCodegenMethods<'tcx> {
operands: &[GlobalAsmOperandRef<'tcx>],
options: InlineAsmOptions,
line_spans: &[Span],
target_features: &[String],
);

/// The mangled name of this instance
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ rustc_apfloat = "0.2.0"
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr_ir = { path = "../rustc_attr_ir" }
rustc_crate_store = { path = "../rustc_crate_store" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ use rustc_arena::TypedArena;
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::tokenstream::TokenStream;
use rustc_attr_ir::lang_items::{LangItem, LanguageItems};
use rustc_attr_ir::{CanonicalSymbols, EiiDecl, EiiImpl, StrippedCfgItem};
use rustc_crate_store::{
CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib,
};
Expand All @@ -63,8 +65,6 @@ use rustc_data_structures::svh::Svh;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::{ErrorGuaranteed, catch_fatal_errors};
use rustc_hir as hir;
use rustc_hir::attrs::lang_items::{LangItem, LanguageItems};
use rustc_hir::attrs::{CanonicalSymbols, EiiDecl, EiiImpl, StrippedCfgItem};
use rustc_hir::def::{DefKind, DocLinkResMap};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdSet, LocalModId};
use rustc_hir::{ItemLocalId, PreciseCapturingArgKind};
Expand Down Expand Up @@ -1524,8 +1524,12 @@ rustc_queries! {

/// Returns the attributes on the item at `def_id`.
///
/// Do not use this directly, use `tcx.get_attrs` instead.
query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] {
/// <div class="warning">
///
/// Do not use this directly, use [`rustc_attr_ir::find_attr`] instead.
///
/// </div>
query attrs_for_def(def_id: DefId) -> &'tcx [rustc_attr_ir::Attribute] {
desc { "collecting attributes of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
Expand Down
Loading
Loading