diff --git a/Cargo.lock b/Cargo.lock index 16250b24d0baf..5fc3a5ac71722 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3700,6 +3700,24 @@ dependencies = [ "thin-vec", ] +[[package]] +name = "rustc_attr_ir" +version = "0.0.0" +dependencies = [ + "rustc_abi", + "rustc_ast", + "rustc_ast_pretty", + "rustc_data_structures", + "rustc_error_messages", + "rustc_macros", + "rustc_serialize", + "rustc_span", + "rustc_target", + "smallvec", + "thin-vec", + "tracing", +] + [[package]] name = "rustc_attr_parsing" version = "0.0.0" @@ -4077,7 +4095,7 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", - "rustc_ast_pretty", + "rustc_attr_ir", "rustc_data_structures", "rustc_error_messages", "rustc_errors", @@ -4089,8 +4107,6 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", - "smallvec", - "thin-vec", "tracing", ] diff --git a/compiler/rustc_attr_ir/Cargo.toml b/compiler/rustc_attr_ir/Cargo.toml new file mode 100644 index 0000000000000..28ca2c8839508 --- /dev/null +++ b/compiler/rustc_attr_ir/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rustc_attr_ir" +version = "0.0.0" +edition = "2024" + +[dependencies] +# tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } +rustc_ast = { path = "../rustc_ast" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_error_messages = { path = "../rustc_error_messages" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2.18" +tracing = "0.1" +# tidy-alphabetical-end diff --git a/compiler/rustc_attr_ir/src/attr.rs b/compiler/rustc_attr_ir/src/attr.rs new file mode 100644 index 0000000000000..6068c11590a23 --- /dev/null +++ b/compiler/rustc_attr_ir/src/attr.rs @@ -0,0 +1,376 @@ +use std::fmt; + +use rustc_ast::attr::AttributeExt; +use rustc_ast::token::DocFragmentKind; +use rustc_ast::{AttrStyle, DelimArgs, MetaItemInner, MetaItemLit, ast, join_path_idents}; +use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; +use rustc_error_messages::{DiagArgValue, IntoDiagArg}; +use rustc_macros::{Decodable, Encodable, StableHash}; +use rustc_span::{AttrId, DUMMY_SP, Ident, Span, Symbol, sym}; +use smallvec::SmallVec; +use thin_vec::ThinVec; + +use crate::AttributeKind; +/// Arguments passed to an attribute macro. +#[derive(Clone, Debug, StableHash, Encodable, Decodable)] +pub enum AttrArgs { + /// No arguments: `#[attr]`. + Empty, + /// Delimited arguments: `#[attr()/[]/{}]`. + Delimited(DelimArgs), + /// Arguments of a key-value attribute: `#[attr = "value"]`. + Eq { + /// Span of the `=` token. + eq_span: Span, + /// The "value". + expr: MetaItemLit, + }, +} + +#[derive(Clone, Debug, StableHash, Encodable, Decodable)] +pub struct AttrPath { + pub segments: Box<[Symbol]>, + pub span: Span, +} + +impl IntoDiagArg for AttrPath { + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(path) + } +} + +impl AttrPath { + pub fn from_ast(path: &ast::Path, lower_span: impl Copy + Fn(Span) -> Span) -> Self { + AttrPath { + segments: path + .segments + .iter() + .map(|i| i.ident.name) + .collect::>() + .into_boxed_slice(), + span: lower_span(path.span), + } + } +} + +impl fmt::Display for AttrPath { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + join_path_idents(self.segments.iter().map(|i| Ident { name: *i, span: DUMMY_SP })) + ) + } +} + +#[derive(Clone, Debug, StableHash, Encodable, Decodable)] +pub struct AttrItem { + // Not lowered to hir::Path because we have no NodeId to resolve to. + pub path: AttrPath, + pub args: AttrArgs, + pub id: HashIgnoredAttrId, + /// Denotes if the attribute decorates the following construct (outer) + /// or the construct this attribute is contained within (inner). + pub style: AttrStyle, + /// Span of the entire attribute + pub span: Span, +} + +/// The derived implementation of [`StableHash`] on [`Attribute`]s shouldn't hash +/// [`AttrId`]s. By wrapping them in this, we make sure we never do. +#[derive(Copy, Debug, Encodable, Decodable, Clone)] +pub struct HashIgnoredAttrId { + pub attr_id: AttrId, +} + +impl StableHash for HashIgnoredAttrId { + fn stable_hash(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { + /* we don't hash HashIgnoredAttrId, we ignore them */ + } +} + +/// Many functions on this type have their documentation in the [`AttributeExt`] trait, +/// since they defer their implementation directly to that trait. +#[derive(Clone, Debug, Encodable, Decodable, StableHash)] +pub enum Attribute { + /// A parsed built-in attribute. + /// + /// Each attribute has a span connected to it. However, you must be somewhat careful using it. + /// That's because sometimes we merge multiple attributes together, like when an item has + /// multiple `repr` attributes. In this case the span might not be very useful. + Parsed(AttributeKind), + + /// An attribute that could not be parsed, out of a token-like representation. + /// This is the case for custom tool attributes. + Unparsed(Box), +} + +impl Attribute { + pub fn get_normal_item(&self) -> &AttrItem { + match &self { + Attribute::Unparsed(normal) => &normal, + _ => panic!("unexpected parsed attribute"), + } + } + + pub fn value_lit(&self) -> Option<&MetaItemLit> { + match &self { + Attribute::Unparsed(n) => match n.as_ref() { + AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr), + _ => None, + }, + _ => None, + } + } + + pub fn is_parsed_attr(&self) -> bool { + match self { + Attribute::Parsed(_) => true, + Attribute::Unparsed(_) => false, + } + } + + pub fn is_prefix_attr_for_suggestions(&self) -> bool { + match self { + Attribute::Unparsed(attr) => attr.span.desugaring_kind().is_none(), + // Other parsed attributes that can appear on expressions originate from source and + // should make suggestions treat the expression like a prefixed form. + Attribute::Parsed(_) => true, + } + } +} + +impl AttributeExt for Attribute { + #[inline] + fn id(&self) -> AttrId { + match &self { + Attribute::Unparsed(u) => u.id.attr_id, + _ => panic!(), + } + } + + #[inline] + fn meta_item_list(&self) -> Option> { + match &self { + Attribute::Unparsed(n) => match n.as_ref() { + AttrItem { args: AttrArgs::Delimited(d), .. } => { + ast::MetaItemKind::list_from_tokens(d.tokens.clone()) + } + _ => None, + }, + _ => None, + } + } + + #[inline] + fn value_str(&self) -> Option { + self.value_lit().and_then(|x| x.value_as_str()) + } + + #[inline] + fn value_span(&self) -> Option { + self.value_lit().map(|i| i.span) + } + + /// For a single-segment attribute, returns its name; otherwise, returns `None`. + #[inline] + fn name(&self) -> Option { + match &self { + Attribute::Unparsed(n) => { + if let [ident] = n.path.segments.as_ref() { + Some(*ident) + } else { + None + } + } + _ => None, + } + } + + #[inline] + fn path_matches(&self, name: &[Symbol]) -> bool { + match &self { + Attribute::Unparsed(n) => n.path.segments.iter().eq(name), + _ => false, + } + } + + #[inline] + fn is_doc_comment(&self) -> Option { + if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self { + Some(*span) + } else { + None + } + } + + #[inline] + fn span(&self) -> Span { + match &self { + Attribute::Unparsed(u) => u.span, + // FIXME: should not be needed anymore when all attrs are parsed + Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, + Attribute::Parsed(AttributeKind::Deprecated { span, .. }) => *span, + Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) => cfgs[0].1, + a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), + } + } + + #[inline] + fn is_word(&self) -> bool { + match &self { + Attribute::Unparsed(n) => { + matches!(n.args, AttrArgs::Empty) + } + _ => false, + } + } + + #[inline] + fn symbol_path(&self) -> Option> { + match &self { + Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()), + _ => None, + } + } + + fn path_span(&self) -> Option { + match &self { + Attribute::Unparsed(attr) => Some(attr.path.span), + Attribute::Parsed(_) => None, + } + } + + #[inline] + fn doc_str(&self) -> Option { + match &self { + Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment), + _ => None, + } + } + + fn is_automatically_derived_attr(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived)) + } + + #[inline] + fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + match &self { + Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { + Some((*comment, *kind)) + } + _ => None, + } + } + + fn doc_resolution_scope(&self) -> Option { + match self { + Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style), + Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => { + Some(attr.style) + } + _ => None, + } + } + + fn is_proc_macro_attr(&self) -> bool { + matches!( + self, + Attribute::Parsed( + AttributeKind::ProcMacro + | AttributeKind::ProcMacroAttribute + | AttributeKind::ProcMacroDerive { .. } + ) + ) + } + + fn is_doc_hidden(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) + } + + fn is_doc_keyword_or_attribute(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some()) + } + + fn is_rustc_doc_primitive(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::RustcDocPrimitive(..))) + } +} + +// FIXME(fn_delegation): use function delegation instead of manually forwarding +impl Attribute { + #[inline] + pub fn id(&self) -> AttrId { + AttributeExt::id(self) + } + + #[inline] + pub fn name(&self) -> Option { + AttributeExt::name(self) + } + + #[inline] + pub fn meta_item_list(&self) -> Option> { + AttributeExt::meta_item_list(self) + } + + #[inline] + pub fn value_str(&self) -> Option { + AttributeExt::value_str(self) + } + + #[inline] + pub fn value_span(&self) -> Option { + AttributeExt::value_span(self) + } + + #[inline] + pub fn path_matches(&self, name: &[Symbol]) -> bool { + AttributeExt::path_matches(self, name) + } + + #[inline] + pub fn is_doc_comment(&self) -> Option { + AttributeExt::is_doc_comment(self) + } + + #[inline] + pub fn has_name(&self, name: Symbol) -> bool { + AttributeExt::has_name(self, name) + } + + #[inline] + pub fn has_any_name(&self, names: &[Symbol]) -> bool { + AttributeExt::has_any_name(self, names) + } + + #[inline] + pub fn span(&self) -> Span { + AttributeExt::span(self) + } + + #[inline] + pub fn is_word(&self) -> bool { + AttributeExt::is_word(self) + } + + #[inline] + pub fn path(&self) -> SmallVec<[Symbol; 1]> { + AttributeExt::path(self) + } + + #[inline] + pub fn doc_str(&self) -> Option { + AttributeExt::doc_str(self) + } + + #[inline] + pub fn is_proc_macro_attr(&self) -> bool { + AttributeExt::is_proc_macro_attr(self) + } + + #[inline] + pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + AttributeExt::doc_str_and_fragment_kind(self) + } +} diff --git a/compiler/rustc_hir/src/attrs/canonical_symbols.rs b/compiler/rustc_attr_ir/src/canonical_symbols.rs similarity index 100% rename from compiler/rustc_hir/src/attrs/canonical_symbols.rs rename to compiler/rustc_attr_ir/src/canonical_symbols.rs diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_attr_ir/src/data_structures.rs similarity index 99% rename from compiler/rustc_hir/src/attrs/data_structures.rs rename to compiler/rustc_attr_ir/src/data_structures.rs index 94241e6a31eb0..5fb57606e14fd 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_attr_ir/src/data_structures.rs @@ -20,10 +20,11 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; pub use rustc_target::spec::SanitizerSet; use thin_vec::ThinVec; -pub use crate::attrs::canonical_symbols::{CanonicalSymbol, CanonicalSymbols}; -use crate::attrs::diagnostic::*; -use crate::attrs::pretty_printing::PrintAttribute; -use crate::{DefaultBodyStability, LangItem, PartialConstStability, Stability}; +pub use crate::canonical_symbols::{CanonicalSymbol, CanonicalSymbols}; +use crate::diagnostic::*; +use crate::lang_items::LangItem; +use crate::pretty_printing::PrintAttribute; +use crate::stability::{DefaultBodyStability, PartialConstStability, Stability}; #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] pub enum EiiImplResolution { diff --git a/compiler/rustc_hir/src/attrs/diagnostic.rs b/compiler/rustc_attr_ir/src/diagnostic.rs similarity index 99% rename from compiler/rustc_hir/src/attrs/diagnostic.rs rename to compiler/rustc_attr_ir/src/diagnostic.rs index 8b309888e98a6..f0bdeb7243816 100644 --- a/compiler/rustc_hir/src/attrs/diagnostic.rs +++ b/compiler/rustc_attr_ir/src/diagnostic.rs @@ -7,7 +7,7 @@ use rustc_span::{DesugaringKind, Span, Symbol, kw}; use thin_vec::ThinVec; use tracing::debug; -use crate::attrs::PrintAttribute; +use crate::PrintAttribute; #[derive(Clone, Default, Debug, StableHash, Encodable, Decodable, PrintAttribute)] pub struct Directive { diff --git a/compiler/rustc_hir/src/diagnostic_items.rs b/compiler/rustc_attr_ir/src/diagnostic_items.rs similarity index 82% rename from compiler/rustc_hir/src/diagnostic_items.rs rename to compiler/rustc_attr_ir/src/diagnostic_items.rs index 5a1901fe88f28..984fea6d43242 100644 --- a/compiler/rustc_hir/src/diagnostic_items.rs +++ b/compiler/rustc_attr_ir/src/diagnostic_items.rs @@ -1,9 +1,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_macros::StableHash; use rustc_span::Symbol; -use rustc_span::def_id::DefIdMap; - -use crate::def_id::DefId; +use rustc_span::def_id::{DefId, DefIdMap}; #[derive(Debug, Default, StableHash)] pub struct DiagnosticItems { diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_attr_ir/src/encode_cross_crate.rs similarity index 99% rename from compiler/rustc_hir/src/attrs/encode_cross_crate.rs rename to compiler/rustc_attr_ir/src/encode_cross_crate.rs index 455af47142446..6a9f37f80868a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_attr_ir/src/encode_cross_crate.rs @@ -1,4 +1,4 @@ -use crate::attrs::AttributeKind; +use crate::AttributeKind; #[derive(PartialEq)] pub enum EncodeCrossCrate { diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_attr_ir/src/lang_items.rs similarity index 99% rename from compiler/rustc_hir/src/lang_items.rs rename to compiler/rustc_attr_ir/src/lang_items.rs index 9d8b0e101d374..34f4fba5b0eea 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_attr_ir/src/lang_items.rs @@ -10,11 +10,11 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; use rustc_macros::{BlobDecodable, Encodable, PrintAttribute, StableHash}; +use rustc_span::def_id::DefId; use rustc_span::{Symbol, kw, sym}; -use crate::attrs::PrintAttribute; -use crate::def_id::DefId; -use crate::{MethodKind, Target}; +use crate::PrintAttribute; +use crate::target::{MethodKind, Target}; /// All of the lang items, defined or not. /// Defined lang items can come from the current crate or its dependencies. diff --git a/compiler/rustc_hir/src/attrs/mod.rs b/compiler/rustc_attr_ir/src/lib.rs similarity index 84% rename from compiler/rustc_hir/src/attrs/mod.rs rename to compiler/rustc_attr_ir/src/lib.rs index 5103784b7b689..588bcfafb208d 100644 --- a/compiler/rustc_hir/src/attrs/mod.rs +++ b/compiler/rustc_attr_ir/src/lib.rs @@ -1,18 +1,37 @@ //! Data structures for representing parsed attributes in the Rust compiler. -//! Formerly `rustc_attr_data_structures`. //! //! For detailed documentation about attribute processing, //! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html). +// tidy-alphabetical-start +#![feature(const_default)] +#![feature(const_trait_impl)] +#![feature(default_field_values)] +#![feature(derive_const)] +#![feature(exhaustive_patterns)] +#![feature(variant_count)] +#![recursion_limit = "256"] +// tidy-alphabetical-end + +pub use attr::*; pub use data_structures::*; pub use encode_cross_crate::EncodeCrossCrate; +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; pub mod diagnostic; +pub mod diagnostic_items; mod encode_cross_crate; +pub mod lang_items; mod pretty_printing; +mod stability; +pub mod target; +pub mod weak_lang_items; /// A trait for types that can provide a list of attributes given a `TyCtxt`. /// @@ -20,7 +39,7 @@ mod pretty_printing; /// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`. /// The concrete implementations are in `rustc_middle`. pub trait HasAttrs<'tcx, Tcx> { - fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::Attribute]; + fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::attr::Attribute]; } /// Finds attributes in sequences of attributes by pattern matching. @@ -72,7 +91,7 @@ macro_rules! find_attr { }; ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ $crate::find_attr!( - $crate::attrs::HasAttrs::get_attrs($id, &$tcx), + $crate::HasAttrs::get_attrs($id, &$tcx), $pattern $(if $guard)? => $e ) }}; @@ -86,7 +105,7 @@ macro_rules! find_attr { 'done: { for i in $attributes_list { #[allow(unused_imports)] - use $crate::attrs::AttributeKind::*; + use $crate::AttributeKind::*; let i: &$crate::Attribute = i; match i { $crate::Attribute::Parsed($pattern) $(if $guard)? => { diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_attr_ir/src/pretty_printing.rs similarity index 100% rename from compiler/rustc_hir/src/attrs/pretty_printing.rs rename to compiler/rustc_attr_ir/src/pretty_printing.rs diff --git a/compiler/rustc_hir/src/stability.rs b/compiler/rustc_attr_ir/src/stability.rs similarity index 99% rename from compiler/rustc_hir/src/stability.rs rename to compiler/rustc_attr_ir/src/stability.rs index 55f0260fc033d..1cba0b59c0f6c 100644 --- a/compiler/rustc_hir/src/stability.rs +++ b/compiler/rustc_attr_ir/src/stability.rs @@ -4,7 +4,7 @@ use rustc_ast::attr::version::RustcVersion; use rustc_macros::{BlobDecodable, Decodable, Encodable, PrintAttribute, StableHash}; use rustc_span::{ErrorGuaranteed, Symbol, sym}; -use crate::attrs::PrintAttribute; +use crate::PrintAttribute; /// The version placeholder that recently stabilized features contain inside the /// `since` field of the `#[stable]` attribute. diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_attr_ir/src/target.rs similarity index 74% rename from compiler/rustc_hir/src/target.rs rename to compiler/rustc_attr_ir/src/target.rs index 2097e860468ec..762ae3b6129e1 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_attr_ir/src/target.rs @@ -6,9 +6,6 @@ use rustc_ast::visit::AssocCtxt; use rustc_ast::{AssocItemKind, ForeignItemKind, ast}; use rustc_macros::StableHash; -use crate::def::DefKind; -use crate::{self as hir, ItemKind, TraitItemKind}; - #[derive(Copy, Clone, PartialEq, Debug, Eq, StableHash)] pub enum GenericParamKind { Type, @@ -299,93 +296,3 @@ impl Target { } } } - -impl From<&hir::ForeignItem<'_>> for Target { - fn from(foreign_item: &hir::ForeignItem<'_>) -> Target { - match foreign_item.kind { - hir::ForeignItemKind::Fn(..) => Target::ForeignFn, - hir::ForeignItemKind::Static(..) => Target::ForeignStatic, - hir::ForeignItemKind::Type => Target::ForeignTy, - } - } -} - -impl From<&hir::GenericParam<'_>> for Target { - fn from(generic_param: &hir::GenericParam<'_>) -> Target { - match generic_param.kind { - hir::GenericParamKind::Type { default, .. } => Target::GenericParam { - kind: GenericParamKind::Type, - has_default: default.is_some(), - }, - hir::GenericParamKind::Lifetime { .. } => { - Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: false } - } - hir::GenericParamKind::Const { default, .. } => Target::GenericParam { - kind: GenericParamKind::Const, - has_default: default.is_some(), - }, - } - } -} - -impl From<&hir::TraitItem<'_>> for Target { - fn from(trait_item: &hir::TraitItem<'_>) -> Target { - match trait_item.kind { - TraitItemKind::Const(..) => Target::AssocConst, - TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { - Target::Method(MethodKind::Trait { body: false }) - } - TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => { - Target::Method(MethodKind::Trait { body: true }) - } - TraitItemKind::Type(..) => Target::AssocTy, - } - } -} - -impl From for Target { - fn from(def_kind: DefKind) -> Target { - match def_kind { - DefKind::ExternCrate => Target::ExternCrate, - DefKind::Use => Target::Use, - DefKind::Static { .. } => Target::Static, - DefKind::Const { .. } => Target::Const, - DefKind::Fn => Target::Fn, - DefKind::Macro(..) => Target::MacroDef, - DefKind::Mod => Target::Mod, - DefKind::ForeignMod => Target::ForeignMod, - DefKind::GlobalAsm => Target::GlobalAsm, - DefKind::TyAlias => Target::TyAlias, - DefKind::Enum => Target::Enum, - DefKind::Struct => Target::Struct, - DefKind::Union => Target::Union, - DefKind::Trait => Target::Trait, - DefKind::TraitAlias => Target::TraitAlias, - DefKind::Impl { of_trait } => Target::Impl { of_trait }, - _ => panic!("impossible case reached"), - } - } -} - -impl From<&hir::Item<'_>> for Target { - fn from(item: &hir::Item<'_>) -> Target { - match item.kind { - ItemKind::ExternCrate(..) => Target::ExternCrate, - ItemKind::Use(..) => Target::Use, - ItemKind::Static { .. } => Target::Static, - ItemKind::Const(..) => Target::Const, - ItemKind::Fn { .. } => Target::Fn, - ItemKind::Macro(..) => Target::MacroDef, - ItemKind::Mod(..) => Target::Mod, - ItemKind::ForeignMod { .. } => Target::ForeignMod, - ItemKind::GlobalAsm { .. } => Target::GlobalAsm, - ItemKind::TyAlias(..) => Target::TyAlias, - ItemKind::Enum(..) => Target::Enum, - ItemKind::Struct(..) => Target::Struct, - ItemKind::Union(..) => Target::Union, - ItemKind::Trait { .. } => Target::Trait, - ItemKind::TraitAlias(..) => Target::TraitAlias, - ItemKind::Impl(imp_) => Target::Impl { of_trait: imp_.of_trait.is_some() }, - } - } -} diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_attr_ir/src/weak_lang_items.rs similarity index 100% rename from compiler/rustc_hir/src/weak_lang_items.rs rename to compiler/rustc_attr_ir/src/weak_lang_items.rs diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index bf3cce6e55624..f9c21f42d4e5e 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -70,27 +70,81 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }) } - /// Find the wrapped inner type of a transparent wrapper. - /// Must not be called on 1-ZST (as they don't have a uniquely defined "wrapped field"). + /// Returns whether the given type has trivial ABI. + fn has_trivial_abi(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, bool> { + if !layout.is_1zst() { + return interp_ok(false); + } + match *layout.ty.kind() { + // Trivially trivial-ABI types (because Rust makes no promises about their ABI). + ty::Tuple(..) + | ty::Never + | ty::FnDef(..) + | ty::Closure(..) + | ty::Coroutine(..) + | ty::CoroutineClosure(..) => interp_ok(true), + + ty::Array(elem, _len) => { + // 0-length arrays are in general *not* okay, but arrays of trivial-ABI types are. + self.has_trivial_abi(self.layout_of(elem)?) + } + ty::Adt(adt_def, _args) => { + if adt_def.repr().transparent() { + // All fields must have trivial ABI. + (0..layout.fields.count()).try_fold(true, |acc, idx| { + interp_ok(acc && self.has_trivial_abi(layout.field(self, idx))?) + }) + } else if adt_def.repr().c() { + interp_ok(false) + } else { + // Must be repr(Rust). + interp_ok(true) + } + } + + ty::Alias(..) => panic!("non-normalized type"), + _ => interp_ok(false), + } + } + + /// Find the wrapped inner type of a transparent wrapper by going for the unique + /// non-trivial-ABI field. /// /// We work with `TyAndLayout` here since that makes it much easier to iterate over all fields. fn unfold_transparent( &self, layout: TyAndLayout<'tcx>, may_unfold: impl Fn(AdtDef<'tcx>) -> bool, - ) -> TyAndLayout<'tcx> { + ) -> InterpResult<'tcx, TyAndLayout<'tcx>> { match layout.ty.kind() { ty::Adt(adt_def, _) if adt_def.repr().transparent() && may_unfold(*adt_def) => { assert_matches!(layout.variants, rustc_abi::Variants::Single { .. }); - // Find the non-1-ZST field, and recurse. - let (_, field) = layout.non_1zst_field(self).unwrap(); + // Look for non-trivial-ABI field(s). + let mut found = None; + for idx in 0..layout.fields.count() { + let field = layout.field(self, idx); + if self.has_trivial_abi(field)? { + continue; + } + // Found a non-trivial ABI field! + if found.is_some() { + // There is more than one such field. + // FIXME: we should just panic here. But currently such repr(transparent) + // types are still accepted. We just don't treat them as transparent. + return interp_ok(layout); + } + found = Some(field); + } + let Some(field) = found else { + // All fields have trivial ABI. That means this type is effectively `()`. + return interp_ok(self.layout_of(self.tcx.types.unit)?); + }; + // Recurse. self.unfold_transparent(field, may_unfold) } - ty::Pat(base, _) => self.layout_of(*base).expect( - "if the layout of a pattern type could be computed, so can the layout of its base", - ), + ty::Pat(base, _) => interp_ok(self.layout_of(*base)?), // Not a transparent type, no further unfolding. - _ => layout, + _ => interp_ok(layout), } } @@ -145,7 +199,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let inner = self.unfold_transparent(inner, /* may_unfold */ |def| { // Stop at NPO types so that we don't miss that attribute in the check below! def.is_struct() && !is_npo(def) - }); + })?; interp_ok(match inner.ty.kind() { ty::Ref(..) | ty::FnPtr(..) => { // Option<&T> behaves like &T, and same for fn() @@ -154,7 +208,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ty::Adt(def, _) if is_npo(*def) => { // Once we found a `nonnull_optimization_guaranteed` type, further strip off // newtype structs from it to find the underlying ABI type. - self.unfold_transparent(inner, /* may_unfold */ |def| def.is_struct()) + self.unfold_transparent(inner, /* may_unfold */ |def| def.is_struct())? } _ => { // Everything else we do not unfold. @@ -175,16 +229,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if caller.ty == callee.ty { return interp_ok(true); } - // 1-ZST are compatible with all 1-ZST (and with nothing else). - if caller.is_1zst() || callee.is_1zst() { - return interp_ok(caller.is_1zst() && callee.is_1zst()); + // Handle trivial-ABI types. + if self.has_trivial_abi(caller)? && self.has_trivial_abi(callee)? { + return interp_ok(true); } // Unfold newtypes and NPO optimizations. let unfold = |layout: TyAndLayout<'tcx>| { - self.unfold_npo(self.unfold_transparent(layout, /* may_unfold */ |_def| true)) + self.unfold_transparent(layout, /* may_unfold */ |_def| true) + .and_then(|f| self.unfold_npo(f)) }; let caller = unfold(caller)?; let callee = unfold(callee)?; + // Not-quite-so-fast path: if the types are equal now, they are compatible. + if caller.ty == callee.ty { + return interp_ok(true); + } // Now see if these inner types are compatible. // Compatible pointer types. For thin pointers, we have to accept even non-`repr(transparent)` @@ -240,8 +299,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return interp_ok(caller == callee); } - // Fall back to exact equality. - interp_ok(caller == callee) + // The rest is incompatible. + interp_ok(false) } /// Returns a `bool` saying whether the two arguments are ABI-compatible. diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2722db0600758..7f7e6f2efb65d 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,8 +1,3 @@ -// tidy-alphabetical-start -#![allow(internal_features)] -#![feature(rustc_attrs)] -// tidy-alphabetical-end - use std::borrow::Cow; pub use fluent_bundle::types::FluentType; @@ -29,7 +24,6 @@ pub fn register_functions(bundle: &mut fluent_bundle::bundle::FluentBundle /// /// Intended to be removed once diagnostics are entirely translatable. #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, StableHash)] -#[rustc_diagnostic_item = "DiagMessage"] pub enum DiagMessage { /// Non-translatable diagnostic message or a message that has been translated eagerly. /// diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index dabb5ef6db8c1..d1dc3ab6e9525 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -8,7 +8,6 @@ use std::path::PathBuf; use std::thread::panicking; use rustc_ast::attr::version::RustcVersion; -use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg}; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; @@ -102,7 +101,6 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { /// rather than the `Diagnostic` impl. /// - Derived impls are always generic, and it's good for the hand-written /// impls to be consistent with them. -#[rustc_diagnostic_item = "Diagnostic"] pub trait Diagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> { /// Write out as a diagnostic out of `DiagCtxt`. #[must_use] @@ -120,16 +118,6 @@ where } } -impl<'a> Diagnostic<'a, ()> - for Box< - dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static, - > -{ - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { - self(dcx, level) - } -} - /// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait. pub struct DiagDecorator)>(pub F); @@ -143,7 +131,6 @@ impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for DiagDecorator { /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic]. -#[rustc_diagnostic_item = "Subdiagnostic"] pub trait Subdiagnostic { /// Add a subdiagnostic to an existing diagnostic. fn add_to_diag(self, diag: &mut Diag<'_, G>); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 08b019917fa9f..4fa104ad6dbfe 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -3,14 +3,11 @@ //! This module contains the code for creating and emitting diagnostics. // tidy-alphabetical-start -#![allow(internal_features)] -#![allow(rustc::direct_use_of_rustc_type_ir)] #![feature(associated_type_defaults)] #![feature(default_field_values)] #![feature(macro_metavar_expr_concat)] #![feature(negative_impls)] #![feature(never_type)] -#![feature(rustc_attrs)] // tidy-alphabetical-end extern crate self as rustc_errors; diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 0d4a8c73e971e..991093cd26914 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -10,7 +10,7 @@ odht = { version = "0.3.1", features = ["nightly"] } rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_errors = { path = "../rustc_errors" } @@ -22,7 +22,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.19" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 6b99f21353e22..cbbaa3b768804 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -4,7 +4,7 @@ rustc_arena::declare_arena! { // HIR types asm_template: rustc_ast::InlineAsmTemplatePiece, - attribute: crate::Attribute, + attribute: rustc_attr_ir::Attribute, owner_info: crate::OwnerInfo<'tcx>, macro_def: rustc_ast::MacroDef, delegation_info: crate::DelegationInfo, diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 9715b108da22a..59e4f084ab81b 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -12,8 +12,8 @@ use rustc_span::Symbol; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::MacroKind; +use crate as hir; use crate::definitions::DefPathData; -use crate::hir; /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct. #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)] diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a465c1d95f6c8..e4d6f052c2246 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4,18 +4,17 @@ use std::fmt; use std::ops::Not; use rustc_abi::ExternAbi; -use rustc_ast::attr::AttributeExt; -use rustc_ast::token::DocFragmentKind; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType, - LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind, join_path_idents, + LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind, }; pub use rustc_ast::{ AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto, MetaItemInner, MetaItemLit, Movability, Mutability, Pinnedness, UnOp, }; +use rustc_attr_ir::Attribute; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; @@ -32,11 +31,8 @@ use rustc_span::{ kw, sym, }; use rustc_target::asm::InlineAsmRegOrRegClass; -use smallvec::SmallVec; -use thin_vec::ThinVec; use tracing::debug; -use crate::attrs::AttributeKind; use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res}; use crate::def_id::{DefId, LocalDefIdMap}; use crate::intravisit::{FnKind, VisitorExt}; @@ -1284,364 +1280,6 @@ pub struct ParentedNode<'tcx> { pub node: Node<'tcx>, } -/// Arguments passed to an attribute macro. -#[derive(Clone, Debug, StableHash, Encodable, Decodable)] -pub enum AttrArgs { - /// No arguments: `#[attr]`. - Empty, - /// Delimited arguments: `#[attr()/[]/{}]`. - Delimited(DelimArgs), - /// Arguments of a key-value attribute: `#[attr = "value"]`. - Eq { - /// Span of the `=` token. - eq_span: Span, - /// The "value". - expr: MetaItemLit, - }, -} - -#[derive(Clone, Debug, StableHash, Encodable, Decodable)] -pub struct AttrPath { - pub segments: Box<[Symbol]>, - pub span: Span, -} - -impl IntoDiagArg for AttrPath { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(path) - } -} - -impl AttrPath { - pub fn from_ast(path: &ast::Path, lower_span: impl Copy + Fn(Span) -> Span) -> Self { - AttrPath { - segments: path - .segments - .iter() - .map(|i| i.ident.name) - .collect::>() - .into_boxed_slice(), - span: lower_span(path.span), - } - } -} - -impl fmt::Display for AttrPath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - join_path_idents(self.segments.iter().map(|i| Ident { name: *i, span: DUMMY_SP })) - ) - } -} - -#[derive(Clone, Debug, StableHash, Encodable, Decodable)] -pub struct AttrItem { - // Not lowered to hir::Path because we have no NodeId to resolve to. - pub path: AttrPath, - pub args: AttrArgs, - pub id: HashIgnoredAttrId, - /// Denotes if the attribute decorates the following construct (outer) - /// or the construct this attribute is contained within (inner). - pub style: AttrStyle, - /// Span of the entire attribute - pub span: Span, -} - -/// The derived implementation of [`StableHash`] on [`Attribute`]s shouldn't hash -/// [`AttrId`]s. By wrapping them in this, we make sure we never do. -#[derive(Copy, Debug, Encodable, Decodable, Clone)] -pub struct HashIgnoredAttrId { - pub attr_id: AttrId, -} - -/// Many functions on this type have their documentation in the [`AttributeExt`] trait, -/// since they defer their implementation directly to that trait. -#[derive(Clone, Debug, Encodable, Decodable, StableHash)] -pub enum Attribute { - /// A parsed built-in attribute. - /// - /// Each attribute has a span connected to it. However, you must be somewhat careful using it. - /// That's because sometimes we merge multiple attributes together, like when an item has - /// multiple `repr` attributes. In this case the span might not be very useful. - Parsed(AttributeKind), - - /// An attribute that could not be parsed, out of a token-like representation. - /// This is the case for custom tool attributes. - Unparsed(Box), -} - -impl Attribute { - pub fn get_normal_item(&self) -> &AttrItem { - match &self { - Attribute::Unparsed(normal) => &normal, - _ => panic!("unexpected parsed attribute"), - } - } - - pub fn value_lit(&self) -> Option<&MetaItemLit> { - match &self { - Attribute::Unparsed(n) => match n.as_ref() { - AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr), - _ => None, - }, - _ => None, - } - } - - pub fn is_parsed_attr(&self) -> bool { - match self { - Attribute::Parsed(_) => true, - Attribute::Unparsed(_) => false, - } - } - - pub fn is_prefix_attr_for_suggestions(&self) -> bool { - match self { - Attribute::Unparsed(attr) => attr.span.desugaring_kind().is_none(), - // Other parsed attributes that can appear on expressions originate from source and - // should make suggestions treat the expression like a prefixed form. - Attribute::Parsed(_) => true, - } - } -} - -impl AttributeExt for Attribute { - #[inline] - fn id(&self) -> AttrId { - match &self { - Attribute::Unparsed(u) => u.id.attr_id, - _ => panic!(), - } - } - - #[inline] - fn meta_item_list(&self) -> Option> { - match &self { - Attribute::Unparsed(n) => match n.as_ref() { - AttrItem { args: AttrArgs::Delimited(d), .. } => { - ast::MetaItemKind::list_from_tokens(d.tokens.clone()) - } - _ => None, - }, - _ => None, - } - } - - #[inline] - fn value_str(&self) -> Option { - self.value_lit().and_then(|x| x.value_as_str()) - } - - #[inline] - fn value_span(&self) -> Option { - self.value_lit().map(|i| i.span) - } - - /// For a single-segment attribute, returns its name; otherwise, returns `None`. - #[inline] - fn name(&self) -> Option { - match &self { - Attribute::Unparsed(n) => { - if let [ident] = n.path.segments.as_ref() { - Some(*ident) - } else { - None - } - } - _ => None, - } - } - - #[inline] - fn path_matches(&self, name: &[Symbol]) -> bool { - match &self { - Attribute::Unparsed(n) => n.path.segments.iter().eq(name), - _ => false, - } - } - - #[inline] - fn is_doc_comment(&self) -> Option { - if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self { - Some(*span) - } else { - None - } - } - - #[inline] - fn span(&self) -> Span { - match &self { - Attribute::Unparsed(u) => u.span, - // FIXME: should not be needed anymore when all attrs are parsed - Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, - Attribute::Parsed(AttributeKind::Deprecated { span, .. }) => *span, - Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) => cfgs[0].1, - a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), - } - } - - #[inline] - fn is_word(&self) -> bool { - match &self { - Attribute::Unparsed(n) => { - matches!(n.args, AttrArgs::Empty) - } - _ => false, - } - } - - #[inline] - fn symbol_path(&self) -> Option> { - match &self { - Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()), - _ => None, - } - } - - fn path_span(&self) -> Option { - match &self { - Attribute::Unparsed(attr) => Some(attr.path.span), - Attribute::Parsed(_) => None, - } - } - - #[inline] - fn doc_str(&self) -> Option { - match &self { - Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment), - _ => None, - } - } - - fn is_automatically_derived_attr(&self) -> bool { - matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived)) - } - - #[inline] - fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { - match &self { - Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { - Some((*comment, *kind)) - } - _ => None, - } - } - - fn doc_resolution_scope(&self) -> Option { - match self { - Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style), - Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => { - Some(attr.style) - } - _ => None, - } - } - - fn is_proc_macro_attr(&self) -> bool { - matches!( - self, - Attribute::Parsed( - AttributeKind::ProcMacro - | AttributeKind::ProcMacroAttribute - | AttributeKind::ProcMacroDerive { .. } - ) - ) - } - - fn is_doc_hidden(&self) -> bool { - matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) - } - - fn is_doc_keyword_or_attribute(&self) -> bool { - matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some()) - } - - fn is_rustc_doc_primitive(&self) -> bool { - matches!(self, Attribute::Parsed(AttributeKind::RustcDocPrimitive(..))) - } -} - -// FIXME(fn_delegation): use function delegation instead of manually forwarding -impl Attribute { - #[inline] - pub fn id(&self) -> AttrId { - AttributeExt::id(self) - } - - #[inline] - pub fn name(&self) -> Option { - AttributeExt::name(self) - } - - #[inline] - pub fn meta_item_list(&self) -> Option> { - AttributeExt::meta_item_list(self) - } - - #[inline] - pub fn value_str(&self) -> Option { - AttributeExt::value_str(self) - } - - #[inline] - pub fn value_span(&self) -> Option { - AttributeExt::value_span(self) - } - - #[inline] - pub fn path_matches(&self, name: &[Symbol]) -> bool { - AttributeExt::path_matches(self, name) - } - - #[inline] - pub fn is_doc_comment(&self) -> Option { - AttributeExt::is_doc_comment(self) - } - - #[inline] - pub fn has_name(&self, name: Symbol) -> bool { - AttributeExt::has_name(self, name) - } - - #[inline] - pub fn has_any_name(&self, names: &[Symbol]) -> bool { - AttributeExt::has_any_name(self, names) - } - - #[inline] - pub fn span(&self) -> Span { - AttributeExt::span(self) - } - - #[inline] - pub fn is_word(&self) -> bool { - AttributeExt::is_word(self) - } - - #[inline] - pub fn path(&self) -> SmallVec<[Symbol; 1]> { - AttributeExt::path(self) - } - - #[inline] - pub fn doc_str(&self) -> Option { - AttributeExt::doc_str(self) - } - - #[inline] - pub fn is_proc_macro_attr(&self) -> bool { - AttributeExt::is_proc_macro_attr(self) - } - - #[inline] - pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { - AttributeExt::doc_str_and_fragment_kind(self) - } -} - /// Attributes owned by a HIR owner. #[derive(Debug)] pub struct AttributeMap<'tcx> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25a6bdea3afe2..83b6e08e22b3c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -66,6 +66,7 @@ use rustc_ast::Label; use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list}; +use rustc_attr_ir::Attribute; use rustc_hir_id::HirId; use rustc_span::def_id::LocalDefId; use rustc_span::{Ident, Span, Symbol}; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 761fc680d2ff6..b073ed4d8ed12 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -11,35 +11,38 @@ #![feature(derive_const)] #![feature(exhaustive_patterns)] #![feature(never_type)] -#![feature(variant_count)] #![recursion_limit = "256"] // tidy-alphabetical-end mod arena; -pub mod attrs; pub mod def; pub mod def_path_hash_map; pub mod definitions; -pub mod diagnostic_items; mod hir; pub mod intravisit; -pub mod lang_items; pub mod lints; pub mod pat_util; -mod stability; mod stable_hash_impls; -pub mod target; -pub mod weak_lang_items; +mod target_impls; #[cfg(test)] mod tests; #[doc(no_inline)] pub use hir::*; -pub use lang_items::{LangItem, LanguageItems}; +pub use rustc_attr_ir::{self as attrs, find_attr}; pub use rustc_hir_id::*; pub use rustc_span::def_id; -pub use stability::*; -pub use target::{MethodKind, Target}; +// FIXME: Remove this use tree, replace by `rustc_hir::attrs` or `rustc_attr_ir` imports +#[doc(hidden)] +pub use { + attrs::target::{self, MethodKind, Target}, + attrs::{ + AttrArgs, AttrItem, AttrPath, Attribute, ConstStability, DefaultBodyStability, + HashIgnoredAttrId, LangItem, LanguageItems, PartialConstStability, Stability, + StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, + }, + attrs::{diagnostic_items, lang_items, weak_lang_items}, +}; pub use crate::arena::Arena; diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 3eadf0744df33..dc0511519958d 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,6 +1,5 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; -use crate::HashIgnoredAttrId; use crate::hir::{AttributeMap, OwnerInfo, OwnerNodes}; // The following implementations of StableHash for `ItemId`, `TraitItemId`, and @@ -36,9 +35,3 @@ impl<'tcx> StableHash for OwnerInfo<'tcx> { opt_hash.unwrap().stable_hash(hcx, hasher); } } - -impl StableHash for HashIgnoredAttrId { - fn stable_hash(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { - /* we don't hash HashIgnoredAttrId, we ignore them */ - } -} diff --git a/compiler/rustc_hir/src/target_impls.rs b/compiler/rustc_hir/src/target_impls.rs new file mode 100644 index 0000000000000..57564bd815595 --- /dev/null +++ b/compiler/rustc_hir/src/target_impls.rs @@ -0,0 +1,96 @@ +//! Implements conversions from HIR types to Target. + +use rustc_attr_ir::target::{GenericParamKind, MethodKind, Target}; + +use crate::def::DefKind; +use crate::{self as hir, ItemKind, TraitItemKind}; + +impl From<&hir::ForeignItem<'_>> for Target { + fn from(foreign_item: &hir::ForeignItem<'_>) -> Target { + match foreign_item.kind { + hir::ForeignItemKind::Fn(..) => Target::ForeignFn, + hir::ForeignItemKind::Static(..) => Target::ForeignStatic, + hir::ForeignItemKind::Type => Target::ForeignTy, + } + } +} + +impl From<&hir::GenericParam<'_>> for Target { + fn from(generic_param: &hir::GenericParam<'_>) -> Target { + match generic_param.kind { + hir::GenericParamKind::Type { default, .. } => Target::GenericParam { + kind: GenericParamKind::Type, + has_default: default.is_some(), + }, + hir::GenericParamKind::Lifetime { .. } => { + Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: false } + } + hir::GenericParamKind::Const { default, .. } => Target::GenericParam { + kind: GenericParamKind::Const, + has_default: default.is_some(), + }, + } + } +} + +impl From<&hir::TraitItem<'_>> for Target { + fn from(trait_item: &hir::TraitItem<'_>) -> Target { + match trait_item.kind { + TraitItemKind::Const(..) => Target::AssocConst, + TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { + Target::Method(MethodKind::Trait { body: false }) + } + TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => { + Target::Method(MethodKind::Trait { body: true }) + } + TraitItemKind::Type(..) => Target::AssocTy, + } + } +} + +impl From for Target { + fn from(def_kind: DefKind) -> Target { + match def_kind { + DefKind::ExternCrate => Target::ExternCrate, + DefKind::Use => Target::Use, + DefKind::Static { .. } => Target::Static, + DefKind::Const { .. } => Target::Const, + DefKind::Fn => Target::Fn, + DefKind::Macro(..) => Target::MacroDef, + DefKind::Mod => Target::Mod, + DefKind::ForeignMod => Target::ForeignMod, + DefKind::GlobalAsm => Target::GlobalAsm, + DefKind::TyAlias => Target::TyAlias, + DefKind::Enum => Target::Enum, + DefKind::Struct => Target::Struct, + DefKind::Union => Target::Union, + DefKind::Trait => Target::Trait, + DefKind::TraitAlias => Target::TraitAlias, + DefKind::Impl { of_trait } => Target::Impl { of_trait }, + _ => panic!("impossible case reached"), + } + } +} + +impl From<&hir::Item<'_>> for Target { + fn from(item: &hir::Item<'_>) -> Target { + match item.kind { + ItemKind::ExternCrate(..) => Target::ExternCrate, + ItemKind::Use(..) => Target::Use, + ItemKind::Static { .. } => Target::Static, + ItemKind::Const(..) => Target::Const, + ItemKind::Fn { .. } => Target::Fn, + ItemKind::Macro(..) => Target::MacroDef, + ItemKind::Mod(..) => Target::Mod, + ItemKind::ForeignMod { .. } => Target::ForeignMod, + ItemKind::GlobalAsm { .. } => Target::GlobalAsm, + ItemKind::TyAlias(..) => Target::TyAlias, + ItemKind::Enum(..) => Target::Enum, + ItemKind::Struct(..) => Target::Struct, + ItemKind::Union(..) => Target::Union, + ItemKind::Trait { .. } => Target::Trait, + ItemKind::TraitAlias(..) => Target::TraitAlias, + ItemKind::Impl(imp_) => Target::Impl { of_trait: imp_.of_trait.is_some() }, + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index fb7d5b6a3133d..b3c80c381ced5 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -20,11 +20,9 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![feature(deref_patterns)] #![feature(iter_order_by)] #![feature(option_into_flat_iter)] -#![feature(rustc_attrs)] #![feature(titlecase)] #![feature(try_blocks)] // tidy-alphabetical-end @@ -165,7 +163,9 @@ early_lint_methods!( [ pub BuiltinCombinedPreExpansionLintPass, [ + // tidy-alphabetical-start KeywordIdents: KeywordIdents, + // tidy-alphabetical-end ] ] ); @@ -175,22 +175,24 @@ early_lint_methods!( [ pub BuiltinCombinedEarlyLintPass, [ - UnusedParens: UnusedParens::default(), - UnusedBraces: UnusedBraces, - UnusedImportBraces: UnusedImportBraces, - UnsafeCode: UnsafeCode, - SpecialModuleName: SpecialModuleName, + // tidy-alphabetical-start AnonymousParameters: AnonymousParameters, + DoubleNegations: DoubleNegations, EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(), - NonCamelCaseTypes: NonCamelCaseTypes, - WhileTrue: WhileTrue, - NonAsciiIdents: NonAsciiIdents, + Expr2024: Expr2024, IncompleteInternalFeatures: IncompleteInternalFeatures, + NonAsciiIdents: NonAsciiIdents, + NonCamelCaseTypes: NonCamelCaseTypes, + Precedence: Precedence, RedundantSemicolons: RedundantSemicolons, + SpecialModuleName: SpecialModuleName, + UnsafeCode: UnsafeCode, + UnusedBraces: UnusedBraces, UnusedDocComment: UnusedDocComment, - Expr2024: Expr2024, - Precedence: Precedence, - DoubleNegations: DoubleNegations, + UnusedImportBraces: UnusedImportBraces, + UnusedParens: UnusedParens::default(), + WhileTrue: WhileTrue, + // tidy-alphabetical-end ] ] ); @@ -200,9 +202,11 @@ early_lint_methods!( [ InternalCombinedEarlyLintPass, [ - LintPassImpl: LintPassImpl, - ImplicitSysrootCrateImport: ImplicitSysrootCrateImport, + // tidy-alphabetical-start BadUseOfFindAttr: BadUseOfFindAttr, + ImplicitSysrootCrateImport: ImplicitSysrootCrateImport, + LintPassImpl: LintPassImpl, + // tidy-alphabetical-end ] ] ); @@ -212,70 +216,72 @@ late_lint_methods!( [ BuiltinCombinedLateLintModPass, [ - ForLoopsOverFallibles: ForLoopsOverFallibles, + // tidy-alphabetical-start + AsmLabels: AsmLabels, + AsyncClosureUsage: AsyncClosureUsage, + AsyncFnInTrait: AsyncFnInTrait, + CVoidReturns: CVoidReturns, + CheckTransmutes: CheckTransmutes, + DanglingPointers: DanglingPointers, DefaultCouldBeDerived: DefaultCouldBeDerived, DerefIntoDynSupertrait: DerefIntoDynSupertrait, + DerefNullPtr: DerefNullPtr, DropForgetUseless: DropForgetUseless, + DropTraitConstraints: DropTraitConstraints, + EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, + ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, + ForLoopsOverFallibles: ForLoopsOverFallibles, + FunctionCastsAsInteger: FunctionCastsAsInteger, + IfLetRescope: IfLetRescope::default(), + ImplTraitOvercaptures: ImplTraitOvercaptures, + ImplicitAutorefs: ImplicitAutorefs, + ImplicitProvenanceCasts: ImplicitProvenanceCasts, ImproperCTypesLint: ImproperCTypesLint, ImproperGpuKernelLint: ImproperGpuKernelLint, + InteriorMutableConsts: InteriorMutableConsts, + InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, + InvalidAtomicOrdering: InvalidAtomicOrdering, InvalidFromUtf8: InvalidFromUtf8, - VariantSizeDifferences: VariantSizeDifferences, - PathStatements: PathStatements, - LetUnderscore: LetUnderscore, + InvalidNoMangleItems: InvalidNoMangleItems, InvalidReferenceCasting: InvalidReferenceCasting, - ImplicitAutorefs: ImplicitAutorefs, - // Depends on referenced function signatures in expressions - UnusedResults: UnusedResults, - UnitBindings: UnitBindings, - NonUpperCaseGlobals: NonUpperCaseGlobals, - NonShorthandFieldPatterns: NonShorthandFieldPatterns, - UnusedAllocation: UnusedAllocation, + InvalidValue: InvalidValue, + LetUnderscore: LetUnderscore, + LifetimeSyntax: LifetimeSyntax, + MapUnitFn: MapUnitFn, // Depends on types used in type definitions MissingCopyImplementations: MissingCopyImplementations, - // Depends on referenced function signatures in expressions - PtrNullChecks: PtrNullChecks, + MissingDebugImplementations: MissingDebugImplementations, + MissingDoc: MissingDoc, + MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, MutableTransmutes: MutableTransmutes, - TypeAliasBounds: TypeAliasBounds, - TrivialConstraints: TrivialConstraints, - TypeLimits: TypeLimits::new(), - NonSnakeCase: NonSnakeCase, - InvalidNoMangleItems: InvalidNoMangleItems, - // Depends on effective visibilities - UnreachablePub: UnreachablePub, - ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, - InvalidValue: InvalidValue, - DerefNullPtr: DerefNullPtr, - UnstableFeatures: UnstableFeatures, - UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, - ShadowedIntoIter: ShadowedIntoIter, - DropTraitConstraints: DropTraitConstraints, - DanglingPointers: DanglingPointers, + NonLocalDefinitions: NonLocalDefinitions::default(), NonPanicFmt: NonPanicFmt, + NonShorthandFieldPatterns: NonShorthandFieldPatterns, + NonSnakeCase: NonSnakeCase, + NonUpperCaseGlobals: NonUpperCaseGlobals, NoopMethodCall: NoopMethodCall, - EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, - InvalidAtomicOrdering: InvalidAtomicOrdering, - AsmLabels: AsmLabels, OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, - MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, - MapUnitFn: MapUnitFn, - MissingDebugImplementations: MissingDebugImplementations, - MissingDoc: MissingDoc, - AsyncClosureUsage: AsyncClosureUsage, - AsyncFnInTrait: AsyncFnInTrait, - NonLocalDefinitions: NonLocalDefinitions::default(), - InteriorMutableConsts: InteriorMutableConsts, + PathStatements: PathStatements, + // Depends on referenced function signatures in expressions + PtrNullChecks: PtrNullChecks, + RawBorrowsViaReferences: RawBorrowsViaReferences, RuntimeSymbols: RuntimeSymbols, - ImplTraitOvercaptures: ImplTraitOvercaptures, - IfLetRescope: IfLetRescope::default(), + ShadowedIntoIter: ShadowedIntoIter, StaticMutRefs: StaticMutRefs, + TrivialConstraints: TrivialConstraints, + TypeAliasBounds: TypeAliasBounds, + TypeLimits: TypeLimits::new(), + UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, + UnitBindings: UnitBindings, UnqualifiedLocalImports: UnqualifiedLocalImports, - FunctionCastsAsInteger: FunctionCastsAsInteger, - CheckTransmutes: CheckTransmutes, - LifetimeSyntax: LifetimeSyntax, - InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, - ImplicitProvenanceCasts: ImplicitProvenanceCasts, - CVoidReturns: CVoidReturns, - RawBorrowsViaReferences: RawBorrowsViaReferences, + // Depends on effective visibilities + UnreachablePub: UnreachablePub, + UnstableFeatures: UnstableFeatures, + UnusedAllocation: UnusedAllocation, + // Depends on referenced function signatures in expressions + UnusedResults: UnusedResults, + VariantSizeDifferences: VariantSizeDifferences, + // tidy-alphabetical-end ] ] ); @@ -285,15 +291,17 @@ late_lint_methods!( [ InternalCombinedLateLintModPass, [ - DefaultHashTypes: DefaultHashTypes, - QueryStability: QueryStability, - TyTyKind: TyTyKind, - TypeIr: TypeIr, + // tidy-alphabetical-start BadOptAccess: BadOptAccess, + DefaultHashTypes: DefaultHashTypes, DisallowedPassByRef: DisallowedPassByRef, + QueryStability: QueryStability, + RustcMustMatchExhaustively: RustcMustMatchExhaustively, SpanUseEqCtxt: SpanUseEqCtxt, SymbolInternStringLiteral: SymbolInternStringLiteral, - RustcMustMatchExhaustively: RustcMustMatchExhaustively, + TyTyKind: TyTyKind, + TypeIr: TypeIr, + // tidy-alphabetical-end ] ] ); diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index c687ed652d74a..3062d53d879a8 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -396,10 +396,7 @@ impl Socket { } else { dur.as_secs() as libc::time_t }; - let mut timeout = libc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as libc::suseconds_t, - }; + let mut timeout = libc::timeval { tv_sec: secs, tv_usec: dur.subsec_micros() as _ }; if timeout.tv_sec == 0 && timeout.tv_usec == 0 { timeout.tv_usec = 1; } diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap index 2daa06d2f4b78..165e270270702 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap @@ -29,6 +29,7 @@ expression: bench - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap index 829ca411eb0e5..a350c9a92c74b 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap @@ -11,6 +11,7 @@ expression: build compiler - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap index 325f21b7fdd70..ef5dd1e832e2b 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap @@ -13,6 +13,7 @@ expression: check - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap index 38693b1f636bf..2ee6f90f68f8c 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap @@ -13,6 +13,7 @@ expression: check compiler - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap index 1d83aa61fdfc2..ab58341ceb9e4 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap @@ -13,6 +13,7 @@ expression: check compiletest --include-default-paths - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap index b409b12093455..f1430e020aaa4 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap @@ -28,6 +28,7 @@ expression: clippy - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap index 15a849db3801e..ce0782792351f 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap @@ -13,6 +13,7 @@ expression: fix - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap index 346a86cb5bd6c..59b84f4301feb 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap @@ -77,6 +77,7 @@ expression: test - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap index d08c6a96942d8..29dc8ee5efcfc 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap @@ -74,6 +74,7 @@ expression: test --skip=coverage - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_map.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_map.snap index b51654bb7d46b..9240e939f946f 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_map.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_map.snap @@ -77,6 +77,7 @@ expression: test --skip=coverage-map - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_run.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_run.snap index bffe4909c6305..f30be2939765a 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_run.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage_run.snap @@ -77,6 +77,7 @@ expression: test --skip=coverage-run - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap index 3ee569401504f..f1aa131eb7c3a 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap @@ -38,6 +38,7 @@ expression: test --skip=tests - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_coverage.snap index c8212e05b46d0..ddf45bcfdbdb1 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_coverage.snap @@ -74,6 +74,7 @@ expression: test --skip=tests/coverage - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap index e41050139f056..c38962f9c12b0 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap @@ -22,6 +22,7 @@ expression: test --skip=tests --skip=library --skip=tidyselftest - Set({compiler/rustc_ast_lowering}) - Set({compiler/rustc_ast_passes}) - Set({compiler/rustc_ast_pretty}) + - Set({compiler/rustc_attr_ir}) - Set({compiler/rustc_attr_parsing}) - Set({compiler/rustc_baked_icu_data}) - Set({compiler/rustc_borrowck}) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 57f50d981d1c4..79b6e86e95b96 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1729,7 +1729,7 @@ mod snapshot { insta::assert_snapshot!( ctx.config("check") .path("compiler") - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] @@ -1755,7 +1755,7 @@ mod snapshot { ctx.config("check") .path("compiler") .stage(1) - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] @@ -1769,7 +1769,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (74 crates) + [check] rustc 1 -> rustc 2 (75 crates) "); } @@ -1785,7 +1785,7 @@ mod snapshot { [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 [check] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (74 crates) + [check] rustc 1 -> rustc 2 (75 crates) [check] rustc 1 -> rustc 2 [check] rustc 1 -> Rustdoc 2 [check] rustc 1 -> rustc_codegen_cranelift 2 @@ -1881,7 +1881,7 @@ mod snapshot { ctx.config("check") .paths(&["library", "compiler"]) .args(&args) - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] @@ -3092,7 +3092,7 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!(ctx.config("fix").path("compiler").render_steps(), @r" [build] llvm - [fix] rustc 0 -> rustc 1 (74 crates) + [fix] rustc 0 -> rustc 1 (75 crates) "); } } diff --git a/src/tools/compiletest/src/cli.rs b/src/tools/compiletest/src/cli.rs index 1325afc2adaa3..1786c68a1889c 100644 --- a/src/tools/compiletest/src/cli.rs +++ b/src/tools/compiletest/src/cli.rs @@ -385,6 +385,13 @@ pub(crate) fn parse_config(args: Vec) -> Config { let iteration_count = args.iteration_count.unwrap_or(Config::DEFAULT_ITERATION_COUNT); assert!(iteration_count > 0, "`--iteration-count` must be a positive integer"); + let gcc_supported_target_tuples = match default_codegen_backend { + CodegenBackend::Gcc => { + directives::find_gcc_supported_targets(&args.sysroot_base, &args.host) + } + CodegenBackend::Llvm | CodegenBackend::Cranelift => vec![], + }; + Config { bless: args.bless, fail_fast: args.fail_fast || env::var_os("RUSTC_TEST_FAIL_FAST").is_some(), @@ -494,6 +501,8 @@ pub(crate) fn parse_config(args: Vec) -> Config { override_codegen_backend: args.override_codegen_backend, bypass_ignore_backends: args.bypass_ignore_backends, + gcc_supported_target_tuples, + jobs: args.jobs, parallel_frontend_threads, diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 82bfa80b2b9c0..de5c50d234661 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -754,6 +754,9 @@ pub(crate) struct Config { /// Whether to ignore `//@ ignore-backends`. pub(crate) bypass_ignore_backends: bool, + /// Target tuples for which we've found libgccjit.so. + pub(crate) gcc_supported_target_tuples: Vec, + /// Number of parallel jobs configured for the build. /// /// This is forwarded from bootstrap's `jobs` configuration. diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index dc10430f038ec..3499821f7b6e0 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -851,6 +851,30 @@ pub(crate) fn extract_llvm_version_from_binary(binary_path: &str) -> Option Vec { + // E.g. `lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/lib`. + let backends_dir = + sysroot_base.join("lib").join("rustlib").join(host).join("codegen-backends").join("lib"); + + match std::fs::read_dir(&backends_dir) { + Ok(entries) => { + // Search for `aarch64-unknown-linux-gnu/libgccjit.so` et cetera. + let target_tuples: Vec<_> = entries + .filter_map(|entry| entry.ok()) + .filter(|entry| entry.path().join("libgccjit.so").exists()) + .filter_map(|entry| entry.file_name().into_string().ok()) + .collect(); + + if target_tuples.is_empty() { + panic!("did not find `libgccjit.so` for any target in {backends_dir}"); + } + + target_tuples + } + Err(e) => panic!("unable to find `libgccjit.so` for any target in {backends_dir}: {e:?}",), + } +} + /// Takes a directive of the form `" [- ]"`, returns the numeric representation /// of `` and `` as tuple: `(, )`. /// @@ -958,6 +982,7 @@ pub(crate) fn make_test_description( decision!(ignore_llvm(config, ln)); decision!(ignore_backends(config, ln)); decision!(needs_backends(config, ln)); + decision!(ignore_unsupported_backend_target(config, ln)); decision!(ignore_cdb(config, variant, ln)); decision!(ignore_gdb(config, variant, ln)); decision!(ignore_lldb(config, variant, ln)); @@ -1212,6 +1237,36 @@ fn needs_backends(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision { IgnoreDecision::Continue } +/// When using the GCC backend, ignore tests for which we did not find a libgccjit.so. +fn ignore_unsupported_backend_target(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision { + if config.default_codegen_backend != crate::CodegenBackend::Gcc { + return IgnoreDecision::Continue; + } + + let Some(compile_flags) = config.parse_name_value_directive(line, "compile-flags") else { + return IgnoreDecision::Continue; + }; + + // See if this line sets a `--target=...` + let Some((_, rest)) = compile_flags.split_once("--target") else { + return IgnoreDecision::Continue; + }; + let Some(target) = rest.trim_start_matches([' ', '=']).split_whitespace().next() else { + return IgnoreDecision::Continue; + }; + + if !config.gcc_supported_target_tuples.iter().any(|t| t == target) { + IgnoreDecision::Ignore { + reason: format!( + "backend `{}` cannot build for target `{target}`", + config.default_codegen_backend.as_str() + ), + } + } else { + IgnoreDecision::Continue + } +} + fn ignore_llvm(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision { let path = line.file_path; if let Some(needed_components) = diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 215fee768f254..7fc37a1a4371d 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -139,6 +139,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { default_codegen_backend: CodegenBackend::Llvm, override_codegen_backend: None, bypass_ignore_backends: Default::default(), + gcc_supported_target_tuples: vec![], jobs: Default::default(), parallel_frontend_threads: Config::DEFAULT_PARALLEL_FRONTEND_THREADS, iteration_count: Config::DEFAULT_ITERATION_COUNT, diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.rs new file mode 100644 index 0000000000000..c9e4badcac464 --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.rs @@ -0,0 +1,8 @@ +fn callee(_s: [u8; 0]) {} +//~^ ERROR: type [u8; 0] passing argument of type () + +fn main() { + let fnptr: fn([u8; 0]) = callee; + let fnptr: fn(()) = unsafe { std::mem::transmute(fnptr) }; + fnptr(()); +} diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.stderr new file mode 100644 index 0000000000000..90f6b87d7635d --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_array.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: calling a function whose parameter #1 has type [u8; 0] passing argument of type () + --> tests/fail/function_pointers/abi_mismatch_zst_array.rs:LL:CC + | +LL | fn callee(_s: [u8; 0]) {} + | ^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets + = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: callee + at tests/fail/function_pointers/abi_mismatch_zst_array.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_zst_array.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs new file mode 100644 index 0000000000000..71911266ebf1f --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs @@ -0,0 +1,11 @@ +#[repr(C)] +struct C; + +fn callee() {} +//~^ ERROR: return type () passing return place of type C + +fn main() { + let fnptr: fn() -> () = callee; + let fnptr: fn() -> C = unsafe { std::mem::transmute(fnptr) }; + fnptr(); +} diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.stderr new file mode 100644 index 0000000000000..bb2f8fc78a29d --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_repr_C.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: calling a function with return type () passing return place of type C + --> tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs:LL:CC + | +LL | fn callee() {} + | ^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets + = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: callee + at tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_zst_repr_C.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs new file mode 100644 index 0000000000000..63608981b1e29 --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs @@ -0,0 +1,11 @@ +#[repr(transparent)] +struct Wrap([u8; 0]); + +fn callee(_s: Wrap) {} +//~^ ERROR: type Wrap passing argument of type () + +fn main() { + let fnptr: fn(Wrap) = callee; + let fnptr: fn(()) = unsafe { std::mem::transmute(fnptr) }; + fnptr(()); +} diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.stderr new file mode 100644 index 0000000000000..5d5e03349fd8e --- /dev/null +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_zst_transparent_array.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: calling a function whose parameter #1 has type Wrap passing argument of type () + --> tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs:LL:CC + | +LL | fn callee(_s: Wrap) {} + | ^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets + = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: callee + at tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_zst_transparent_array.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs index 94cb5695fac50..56c45eb29a0bf 100644 --- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs +++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs @@ -62,11 +62,11 @@ fn test_abi_newtype() { struct Wrapper2a((), T); #[repr(transparent)] #[derive(Copy, Clone)] - struct Wrapper3(Zst, T, [u8; 0]); + struct Wrapper3(Zst, T, [(); 0]); #[repr(transparent)] #[derive(Copy, Clone)] enum Wrapper4 { - V(Zst, T, [u8; 0]), + V(Zst, T, [(); 10]), } let t = T::default(); @@ -74,7 +74,7 @@ fn test_abi_newtype() { test_abi_compat(t, Wrapper2(t, ())); test_abi_compat(t, Wrapper2a((), t)); test_abi_compat(t, Wrapper3(Zst, t, [])); - test_abi_compat(t, Wrapper4::V(Zst, t, [])); + test_abi_compat(t, Wrapper4::V(Zst, t, [(); _])); // MaybeUninit is `repr(transparent)`; that covers the `union` case. test_abi_compat(t, mem::MaybeUninit::new(t)); } @@ -100,8 +100,8 @@ fn main() { test_abi_compat(&0u32, &([true; 4], [0u32; 0])); // - `fn` types test_abi_compat(main as fn(), id:: as fn(i32) -> i32); - // - 1-ZST - test_abi_compat((), [0u8; 0]); + // - trivial-ABI types + test_abi_compat((), [(); 0]); // Guaranteed null-pointer-layout optimizations: // - Guaranteed Option null-pointer-optimizations (RFC 3391). diff --git a/tests/incremental/adt_sized_constraint_struct_enum.rs b/tests/incremental/adt_sized_constraint_struct_enum.rs new file mode 100644 index 0000000000000..a9f00217fb935 --- /dev/null +++ b/tests/incremental/adt_sized_constraint_struct_enum.rs @@ -0,0 +1,62 @@ +//! Regression test for +//@ revisions: rpass1 rpass2 +//@ edition:2021 +#![allow(dead_code)] + +use std::future::Future; +use std::marker::PhantomData; +use std::pin::Pin; +use std::task::{Context, Poll}; + +#[cfg(rpass1)] +struct SourceDocument {} + +#[cfg(rpass2)] +enum SourceDocument {} + +trait Loader { + type Value; + fn load(&self) -> impl Future; +} + +struct SourceDocumentLoader; +impl Loader for SourceDocumentLoader { + type Value = SourceDocument; + async fn load(&self) -> Self::Value { + todo!() + } +} + +struct ManualSend(T); +unsafe impl Send for ManualSend {} + +struct PendingButCovariant(PhantomData); +impl Future for PendingButCovariant { + type Output = T; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +struct DataLoader(T); +impl DataLoader { + async fn load_one(&self) -> ManualSend + where + T: Loader, + { + PendingButCovariant(PhantomData).await + } +} + +trait ContainerType { + fn resolve_field(&self) -> impl Future + Send; +} +impl ContainerType for () { + async fn resolve_field(&self) { + let loader = DataLoader(SourceDocumentLoader); + loader.load_one().await; + } +} + +fn main() {} diff --git a/tests/ui/asm/naked-functions/instruction-set.rs b/tests/ui/asm/naked-functions/instruction-set.rs index 8c796ff8b262b..4d60afa57b222 100644 --- a/tests/ui/asm/naked-functions/instruction-set.rs +++ b/tests/ui/asm/naked-functions/instruction-set.rs @@ -2,7 +2,6 @@ //@ compile-flags: --target armv5te-unknown-linux-gnueabi //@ needs-llvm-components: arm //@ build-pass -//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core)] diff --git a/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.rs b/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.rs new file mode 100644 index 0000000000000..001be82d5ea3a --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.rs @@ -0,0 +1,33 @@ +//! Regression test for . + +//@ incremental + +#![allow(incomplete_features)] +#![feature(adt_const_params, unsized_const_params, generic_const_exprs)] + +const fn concat_strs() -> &'static str { + //~^ ERROR mismatched types + const fn concat_arr(a: [u8; M], b: [u8; N]) -> [u8; M + N] {} + //~^ ERROR mismatched types + + impl Inner + //~^ ERROR cannot find type `Inner` in this scope + where + [(); A.len()]:, + [(); B.len()]:, + [(); A.len() + B.len()]:, + { + const ABSTR: &'static str = unsafe { + std::str::from_utf8_unchecked(&concat_arr( + A.as_ptr().cast().read(), + //~^ WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + B.as_ptr().cast().read(), + //~^ WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + )) + }; + } +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.stderr b/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.stderr new file mode 100644 index 0000000000000..5d4b5fd294036 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/cannot-convert-erased-region-vid-ice-125564.stderr @@ -0,0 +1,51 @@ +error[E0425]: cannot find type `Inner` in this scope + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:13:56 + | +LL | impl Inner + | ^^^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:8:27 + | +LL | const fn concat_strs() -> &'static str { + | ----------- ^^^^^^^^^^^^ expected `&str`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error[E0308]: mismatched types + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:10:84 + | +LL | const fn concat_arr(a: [u8; M], b: [u8; N]) -> [u8; M + N] {} + | ---------- ^^^^^^^^^^^ expected `[u8; M + N]`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +note: consider returning one of these bindings + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:10:57 + | +LL | const fn concat_arr(a: [u8; M], b: [u8; N]) -> [u8; M + N] {} + | ^ ^ + +warning: type annotations needed + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:22:35 + | +LL | A.as_ptr().cast().read(), + | ^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see + = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default + +warning: type annotations needed + --> $DIR/cannot-convert-erased-region-vid-ice-125564.rs:25:35 + | +LL | B.as_ptr().cast().read(), + | ^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see + +error: aborting due to 3 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.rs b/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.rs new file mode 100644 index 0000000000000..9ea1e5a105506 --- /dev/null +++ b/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.rs @@ -0,0 +1,35 @@ +//! Regression test for . +//! +//! `X` is only implemented for `fn(&'a ())` for some specific `'a`, so neither the +//! indirect call through a generic parameter nor the direct call may use it at the +//! higher-ranked type `for<'a> fn(&'a ())`. Both are rejected now; the indirect one +//! used to be accepted. + +trait X { + type G; + fn make_g() -> Self::G; +} + +impl<'a> X for fn(&'a ()) { + type G = &'a (); + + fn make_g() -> Self::G { + &() + } +} + +fn indirect() { + let x = T::make_g(); +} + +fn call_indirect() { + indirect::(); + //~^ ERROR implementation of `X` is not general enough +} + +fn direct() { + let x = ::make_g(); + //~^ ERROR no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope +} + +fn main() {} diff --git a/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.stderr b/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.stderr new file mode 100644 index 0000000000000..c8d88b6243c4f --- /dev/null +++ b/tests/ui/higher-ranked/hrtb-fn-ptr-impl-not-general-enough-57936.stderr @@ -0,0 +1,25 @@ +error[E0599]: no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope + --> $DIR/hrtb-fn-ptr-impl-not-general-enough-57936.rs:31:24 + | +LL | let x = ::make_g(); + | ^^^^^^ associated function or constant not found in `for<'a> fn(&'a ())` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `X` defines an item `make_g`, perhaps you need to implement it + --> $DIR/hrtb-fn-ptr-impl-not-general-enough-57936.rs:8:1 + | +LL | trait X { + | ^^^^^^^ + +error: implementation of `X` is not general enough + --> $DIR/hrtb-fn-ptr-impl-not-general-enough-57936.rs:26:5 + | +LL | indirect::(); + | ^^^^^^^^^^^^^^^^^^^^^ implementation of `X` is not general enough + | + = note: `X` would have to be implemented for the type `for<'a> fn(&'a ())` + = note: ...but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr index 7656228a85c12..6a92ddf3df099 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr @@ -24,6 +24,12 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters LL | union U where i32: Foo { f: i32 } | ^^^ +warning: trait bound i32: Foo does not depend on any type or lifetime parameters + --> $DIR/trivial-bounds-inconsistent.rs:22:19 + | +LL | type Y where i32: Foo = (); + | ^^^ + warning: where clauses on type aliases are not enforced --> $DIR/trivial-bounds-inconsistent.rs:22:14 | @@ -40,12 +46,6 @@ LL - type Y where i32: Foo = (); LL + type Y = (); | -warning: trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:22:19 - | -LL | type Y where i32: Foo = (); - | ^^^ - warning: trait bound i32: Foo does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent.rs:26:28 | diff --git a/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.rs b/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.rs new file mode 100644 index 0000000000000..6e29b12b1d3b1 --- /dev/null +++ b/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.rs @@ -0,0 +1,20 @@ +//! Regression test for . +//! +//! Only the `E0119` conflicting-implementations error used to be reported here, which hid the +//! actual mistake: the unsized field is not the last field of the struct. Both errors are now +//! emitted. + +use std::marker::PhantomData; + +trait Trait {} + +struct Unsized([u8], ()); +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + +struct Foo(PhantomData); + +impl Trait for Foo {} +impl Trait for Foo {} +//~^ ERROR conflicting implementations of trait `Trait` for type `Foo` + +fn main() {} diff --git a/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.stderr b/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.stderr new file mode 100644 index 0000000000000..5f398bef07f2e --- /dev/null +++ b/tests/ui/unsized/unsized-non-last-field-overlapping-impls-83097.stderr @@ -0,0 +1,30 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-last-field-overlapping-impls-83097.rs:11:16 + | +LL | struct Unsized([u8], ()); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct Unsized(&[u8], ()); + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | struct Unsized(Box<[u8]>, ()); + | ++++ + + +error[E0119]: conflicting implementations of trait `Trait` for type `Foo` + --> $DIR/unsized-non-last-field-overlapping-impls-83097.rs:17:1 + | +LL | impl Trait for Foo {} + | ------------------------ first implementation here +LL | impl Trait for Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0277. +For more information about an error, try `rustc --explain E0119`. diff --git a/triagebot.toml b/triagebot.toml index d5e58db589b22..763c668fe7881 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -291,7 +291,7 @@ trigger_files = [ "compiler/rustc_codegen_ssa/src/codegen_attrs.rs", "compiler/rustc_passes/src/check_attr.rs", "compiler/rustc_attr_parsing", - "compiler/rustc_hir/src/attrs", + "compiler/rustc_attr_ir", ] [autolabel."A-compiler-builtins"] @@ -1490,7 +1490,7 @@ cc = ["@BoxyUwU", "@tshepang"] cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."compiler/rustc_attr_parsing"] cc = ["@jdonszelmann", "@JonathanBrouwer"] -[mentions."compiler/rustc_hir/src/attrs"] +[mentions."compiler/rustc_attr_ir"] cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."src/tools/enzyme"] @@ -1525,7 +1525,7 @@ cc = ["@jieyouxu"] [mentions."compiler/rustc_attr_parsing/src/attributes/diagnostic"] message = "Some changes occurred to diagnostic attributes." cc = ["@mejrs"] -[mentions."compiler/rustc_hir/src/attrs/diagnostic.rs"] +[mentions."compiler/rustc_attr_ir/src/diagnostic.rs"] message = "Some changes occurred to diagnostic attributes." cc = ["@mejrs"] @@ -1607,6 +1607,7 @@ infra-ci = [ "@marcoieni", "@jdno", "@jieyouxu", + "@ubiratansoares" ] docs = [ "@GuillaumeGomez",