diff --git a/Cargo.lock b/Cargo.lock index 1cff2f22f4f6b..4fa2936227654 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4474,6 +4474,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_hir", + "rustc_index", "rustc_macros", "rustc_metadata", "rustc_middle", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 491a9bbda79b1..3c576316f6230 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2422,7 +2422,7 @@ impl Ty { } #[derive(Clone, Encodable, Decodable, Debug)] -pub struct BareFnTy { +pub struct FnPtrTy { pub safety: Safety, pub ext: Extern, pub generic_params: ThinVec, @@ -2455,8 +2455,8 @@ pub enum TyKind { /// /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`. PinnedRef(Option, MutTy), - /// A bare function (e.g., `fn(usize) -> bool`). - BareFn(P), + /// A function pointer type (e.g., `fn(usize) -> bool`). + FnPtr(P), /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`). UnsafeBinder(P), /// The never type (`!`). diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 989ebe14bf8fc..f7daec4b0648c 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -265,7 +265,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { ty = &binder.inner_ty; } - ast::TyKind::BareFn(fn_ty) => match &fn_ty.decl.output { + ast::TyKind::FnPtr(fn_ty) => match &fn_ty.decl.output { ast::FnRetTy::Default(_) => break None, ast::FnRetTy::Ty(ret) => ty = ret, }, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index f8ecff69a7635..37fcc0d2167b2 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1059,8 +1059,8 @@ macro_rules! common_visitor_and_walkers { TyKind::Tup(tuple_element_types) => { walk_list!(vis, visit_ty, tuple_element_types); } - TyKind::BareFn(function_declaration) => { - let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = + TyKind::FnPtr(function_declaration) => { + let FnPtrTy { safety, ext: _, generic_params, decl, decl_span } = &$($mut)? **function_declaration; try_visit!(visit_safety(vis, safety)); try_visit!(visit_generic_params(vis, generic_params)); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0706bdb119f01..348fe2ee40aa2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1269,9 +1269,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args)); hir::TyKind::Path(path) } - TyKind::BareFn(f) => { + TyKind::FnPtr(f) => { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); - hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { + hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy { generic_params, safety: self.lower_safety(f.safety, hir::Safety::Safe), abi: self.lower_extern(f.ext), diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index d58c140c696d8..c5780c957c974 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -48,9 +48,6 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim ast_passes_bad_c_variadic = only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg -ast_passes_bare_fn_invalid_safety = function pointers cannot be declared with `safe` safety qualifier - .suggestion = remove safe from this item - ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block .cannot_have = cannot have a body .invalid = the invalid body @@ -135,6 +132,9 @@ ast_passes_fn_param_forbidden_self = ast_passes_fn_param_too_many = function can not have more than {$max_num_args} arguments +ast_passes_fn_ptr_invalid_safety = function pointers cannot be declared with `safe` safety qualifier + .suggestion = remove safe from this item + ast_passes_fn_without_body = free function without a body .suggestion = provide a definition for the function diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 53e2a1c695a8f..38889d28151b3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -499,9 +499,9 @@ impl<'a> AstValidator<'a> { } } - fn check_bare_fn_safety(&self, span: Span, safety: Safety) { + fn check_fn_ptr_safety(&self, span: Span, safety: Safety) { if matches!(safety, Safety::Safe(_)) { - self.dcx().emit_err(errors::InvalidSafetyOnBareFn { span }); + self.dcx().emit_err(errors::InvalidSafetyOnFnPtr { span }); } } @@ -785,8 +785,8 @@ impl<'a> AstValidator<'a> { fn visit_ty_common(&mut self, ty: &'a Ty) { match &ty.kind { - TyKind::BareFn(bfty) => { - self.check_bare_fn_safety(bfty.decl_span, bfty.safety); + TyKind::FnPtr(bfty) => { + self.check_fn_ptr_safety(bfty.decl_span, bfty.safety); self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _, _| { self.dcx().emit_err(errors::PatternFnPointer { span }); diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index d387a4a310ea0..3b2730d4ff9de 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -225,8 +225,8 @@ pub(crate) struct InvalidSafetyOnItem { } #[derive(Diagnostic)] -#[diag(ast_passes_bare_fn_invalid_safety)] -pub(crate) struct InvalidSafetyOnBareFn { +#[diag(ast_passes_fn_ptr_invalid_safety)] +pub(crate) struct InvalidSafetyOnFnPtr { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 5d8ee07178d2b..8114733f40670 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -286,9 +286,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_ty(&mut self, ty: &'a ast::Ty) { match &ty.kind { - ast::TyKind::BareFn(bare_fn_ty) => { + ast::TyKind::FnPtr(fn_ptr_ty) => { // Function pointers cannot be `const` - self.check_late_bound_lifetime_defs(&bare_fn_ty.generic_params); + self.check_late_bound_lifetime_defs(&fn_ptr_ty.generic_params); } ast::TyKind::Never => { gate!(&self, never_type, ty.span, "the `!` type is experimental"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9802ac90c9a65..aff98c63bcb41 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1285,7 +1285,7 @@ impl<'a> State<'a> { self.print_type(typ); self.pclose(); } - ast::TyKind::BareFn(f) => { + ast::TyKind::FnPtr(f) => { self.print_ty_fn(f.ext, f.safety, &f.decl, None, &f.generic_params); } ast::TyKind::UnsafeBinder(f) => { diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index ba62be676d46b..2cbb727078577 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -149,7 +149,7 @@ pub enum UsedBy { /// ## Attribute Processing /// While attributes are initially parsed by [`rustc_parse`] into [`ast::Attribute`], they still contain raw token streams /// because different attributes have different internal structures. This enum represents the final, -/// fully parsed form of these attributes, where each variant contains contains all the information and +/// fully parsed form of these attributes, where each variant contains all the information and /// structure relevant for the specific attribute. /// /// Some attributes can be applied multiple times to the same item, and they are "collapsed" into a single @@ -298,6 +298,9 @@ pub enum AttributeKind { /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). PassByValue(Span), + /// Represents `#[path]` + Path(Symbol, Span), + /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). PubTransparent(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index b109ebbf47bb2..a6ae49d280873 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { NonExhaustive(..) => Yes, Optimize(..) => No, PassByValue(..) => Yes, + Path(..) => No, PubTransparent(..) => Yes, Repr { .. } => No, RustcLayoutScalarValidRangeEnd(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 55fbb82546632..ba7572434dfa6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -37,6 +37,7 @@ pub(crate) mod loop_match; pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; pub(crate) mod non_exhaustive; +pub(crate) mod path; pub(crate) mod repr; pub(crate) mod rustc_internal; pub(crate) mod semantics; diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs new file mode 100644 index 0000000000000..0dfbc9a9aa875 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/path.rs @@ -0,0 +1,29 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::{Symbol, sym}; + +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct PathParser; + +impl SingleAttributeParser for PathParser { + const PATH: &[Symbol] = &[sym::path]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "file"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + let Some(path) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + Some(AttributeKind::Path(path, cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bcd7b024a9ea9..939f4a6fde705 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -28,6 +28,7 @@ use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; +use crate::attributes::path::PathParser as PathAttributeParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, @@ -133,6 +134,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 8135f3744f898..8c3093acea450 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -414,12 +414,12 @@ fn find_type_parameters( impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> { fn visit_ty(&mut self, ty: &'a ast::Ty) { let stack_len = self.bound_generic_params_stack.len(); - if let ast::TyKind::BareFn(bare_fn) = &ty.kind - && !bare_fn.generic_params.is_empty() + if let ast::TyKind::FnPtr(fn_ptr) = &ty.kind + && !fn_ptr.generic_params.is_empty() { // Given a field `x: for<'a> fn(T::SomeType<'a>)`, we wan't to account for `'a` so // that we generate `where for<'a> T::SomeType<'a>: ::core::clone::Clone`. #122622 - self.bound_generic_params_stack.extend(bare_fn.generic_params.iter().cloned()); + self.bound_generic_params_stack.extend(fn_ptr.generic_params.iter().cloned()); } if let ast::TyKind::Path(_, path) = &ty.kind diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index be63bb8ac59f1..ff4544278714f 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -4,7 +4,7 @@ use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; use rustc_attr_data_structures::{ - AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, UsedBy, find_attr, + AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, UsedBy, find_attr, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; @@ -109,14 +109,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let hir::Attribute::Parsed(p) = attr { match p { - AttributeKind::Repr { reprs, first_span: _ } => { - codegen_fn_attrs.alignment = reprs - .iter() - .filter_map( - |(r, _)| if let ReprAttr::ReprAlign(x) = r { Some(*x) } else { None }, - ) - .max(); - } AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, AttributeKind::ExportName { name, .. } => { codegen_fn_attrs.export_name = Some(*name); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 459fe5935e06e..df010f8709829 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -831,7 +831,7 @@ pub enum LifetimeRes { /// Id of the introducing place. That can be: /// - an item's id, for the item's generic parameters; /// - a TraitRef's ref_id, identifying the `for<...>` binder; - /// - a BareFn type's id. + /// - a FnPtr type's id. /// /// This information is used for impl-trait lifetime captures, to know when to or not to /// capture any given lifetime. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 559a771931e9c..0f6f81d7964c4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3526,7 +3526,7 @@ impl PrimTy { } #[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct BareFnTy<'hir> { +pub struct FnPtrTy<'hir> { pub safety: Safety, pub abi: ExternAbi, pub generic_params: &'hir [GenericParam<'hir>], @@ -3645,8 +3645,8 @@ pub enum TyKind<'hir, Unambig = ()> { Ptr(MutTy<'hir>), /// A reference (i.e., `&'a T` or `&'a mut T`). Ref(&'hir Lifetime, MutTy<'hir>), - /// A bare function (e.g., `fn(usize) -> bool`). - BareFn(&'hir BareFnTy<'hir>), + /// A function pointer (e.g., `fn(usize) -> bool`). + FnPtr(&'hir FnPtrTy<'hir>), /// An unsafe binder type (e.g. `unsafe<'a> Foo<'a>`). UnsafeBinder(&'hir UnsafeBinderTy<'hir>), /// The never type (`!`). @@ -4498,7 +4498,7 @@ pub enum ForeignItemKind<'hir> { /// /// All argument idents are actually always present (i.e. `Some`), but /// `&[Option]` is used because of code paths shared with `TraitFn` - /// and `BareFnTy`. The sharing is due to all of these cases not allowing + /// and `FnPtrTy`. The sharing is due to all of these cases not allowing /// arbitrary patterns for parameters. Fn(FnSig<'hir>, &'hir [Option], &'hir Generics<'hir>), /// A foreign static item (`static ext: u8`). diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index a0bc318e2ca66..1bb8f7ad8945a 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1001,7 +1001,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) - TyKind::Tup(tuple_element_types) => { walk_list!(visitor, visit_ty_unambig, tuple_element_types); } - TyKind::BareFn(ref function_declaration) => { + TyKind::FnPtr(ref function_declaration) => { walk_list!(visitor, visit_generic_param, function_declaration.generic_params); try_visit!(visitor.visit_fn_decl(function_declaration.decl)); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 25064c327d051..a185291887dc7 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -198,7 +198,7 @@ fn placeholder_type_error_diag<'cx, 'tcx>( let mut is_const_or_static = false; if let Some(hir_ty) = hir_ty - && let hir::TyKind::BareFn(_) = hir_ty.kind + && let hir::TyKind::FnPtr(_) = hir_ty.kind { is_fn = true; diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 573af01a62d49..31e9c3b80fba2 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -454,7 +454,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option; fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) -> ControlFlow { match ty.kind { - hir::TyKind::BareFn(..) => { + hir::TyKind::FnPtr(..) => { self.outer_index.shift_in(1); let res = intravisit::walk_ty(self, ty); self.outer_index.shift_out(1); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index a0d1273eb8586..8d7ac7db67bdc 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -704,7 +704,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { match ty.kind { - hir::TyKind::BareFn(c) => { + hir::TyKind::FnPtr(c) => { let (mut bound_vars, binders): (FxIndexMap, Vec<_>) = c .generic_params .iter() @@ -728,8 +728,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { where_bound_origin: None, }; self.with(scope, |this| { - // a bare fn has no bounds, so everything - // contained within is scoped within its binder. + // a FnPtr has no bounds, so everything within is scoped within its binder intravisit::walk_ty(this, ty); }); } @@ -758,8 +757,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { where_bound_origin: None, }; self.with(scope, |this| { - // a bare fn has no bounds, so everything - // contained within is scoped within its binder. + // everything within is scoped within its binder intravisit::walk_ty(this, ty); }); } @@ -1419,7 +1417,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { hir::Node::OpaqueTy(_) => "higher-ranked lifetime from outer `impl Trait`", // Other items are fine. hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => return Ok(()), - hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(_), .. }) => { + hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(_), .. }) => { "higher-ranked lifetime from function pointer" } hir::Node::Ty(hir::Ty { kind: hir::TyKind::TraitObject(..), .. }) => { diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index ef789743e06f7..3f928fd056e4e 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -393,9 +393,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let params = if let Some(generics) = node.generics() { generics.params } else if let hir::Node::Ty(ty) = node - && let hir::TyKind::BareFn(bare_fn) = ty.kind + && let hir::TyKind::FnPtr(fn_ptr) = ty.kind { - bare_fn.generic_params + fn_ptr.generic_params } else { &[] }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 82e5f65476ff9..5088c63702e60 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -21,8 +21,8 @@ pub(crate) fn validate_cmse_abi<'tcx>( ExternAbi::CmseNonSecureCall => { let hir_node = tcx.hir_node(hir_id); let hir::Node::Ty(hir::Ty { - span: bare_fn_span, - kind: hir::TyKind::BareFn(bare_fn_ty), + span: fn_ptr_span, + kind: hir::TyKind::FnPtr(fn_ptr_ty), .. }) = hir_node else { @@ -49,18 +49,18 @@ pub(crate) fn validate_cmse_abi<'tcx>( Ok(Err(index)) => { // fn(x: u32, u32, u32, u16, y: u16) -> u32, // ^^^^^^ - let span = if let Some(ident) = bare_fn_ty.param_idents[index] { - ident.span.to(bare_fn_ty.decl.inputs[index].span) + let span = if let Some(ident) = fn_ptr_ty.param_idents[index] { + ident.span.to(fn_ptr_ty.decl.inputs[index].span) } else { - bare_fn_ty.decl.inputs[index].span + fn_ptr_ty.decl.inputs[index].span } - .to(bare_fn_ty.decl.inputs.last().unwrap().span); - let plural = bare_fn_ty.param_idents.len() - index != 1; + .to(fn_ptr_ty.decl.inputs.last().unwrap().span); + let plural = fn_ptr_ty.param_idents.len() - index != 1; dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi }); } Err(layout_err) => { if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span }); + dcx.emit_err(errors::CmseCallGeneric { span: *fn_ptr_span }); } } } @@ -68,12 +68,12 @@ pub(crate) fn validate_cmse_abi<'tcx>( match is_valid_cmse_output(tcx, fn_sig) { Ok(true) => {} Ok(false) => { - let span = bare_fn_ty.decl.output.span(); + let span = fn_ptr_ty.decl.output.span(); dcx.emit_err(errors::CmseOutputStackSpill { span, abi }); } Err(layout_err) => { if should_emit_generic_error(abi, layout_err) { - dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span }); + dcx.emit_err(errors::CmseCallGeneric { span: *fn_ptr_span }); } } }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 434375060dffe..20d165897e2a3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2402,7 +2402,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::TyKind::Tup(fields) => { Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t))) } - hir::TyKind::BareFn(bf) => { + hir::TyKind::FnPtr(bf) => { require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span); Ty::new_fn_ptr( @@ -2660,28 +2660,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?output_ty); let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi); - let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); + let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); - if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) = + if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), span, .. }) = tcx.hir_node(hir_id) { - check_abi(tcx, hir_id, *span, bare_fn_ty.abi); + check_abi(tcx, hir_id, *span, fn_ptr_ty.abi); } // reject function types that violate cmse ABI requirements - cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty); + cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, fn_ptr_ty); - if !bare_fn_ty.references_error() { + if !fn_ptr_ty.references_error() { // Find any late-bound regions declared in return type that do // not appear in the arguments. These are not well-formed. // // Example: // for<'a> fn() -> &'a str <-- 'a is bad // for<'a> fn(&'a String) -> &'a str <-- 'a is ok - let inputs = bare_fn_ty.inputs(); + let inputs = fn_ptr_ty.inputs(); let late_bound_in_args = tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned())); - let output = bare_fn_ty.output(); + let output = fn_ptr_ty.output(); let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output); self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| { @@ -2695,7 +2695,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); } - bare_fn_ty + fn_ptr_ty } /// Given a fn_hir_id for a impl function, suggest the type that is found on the diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index c523a03e012e4..3a525021f6fc9 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -405,7 +405,7 @@ impl<'a> State<'a> { } self.pclose(); } - hir::TyKind::BareFn(f) => { + hir::TyKind::FnPtr(f) => { self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_idents); } hir::TyKind::UnsafeBinder(unsafe_binder) => { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 8c1399aec147b..7611f8ac3e1a7 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -203,7 +203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let adjusted_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false)); - // If the callee is a bare function or a closure, then we're all set. + // If the callee is a function pointer or a closure, then we're all set. match *adjusted_ty.kind() { ty::FnDef(..) | ty::FnPtr(..) => { let adjustments = self.adjust_steps(autoderef); diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index ad7686b3e5b78..bc9badbb232e6 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -431,7 +431,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_, hir::AmbigArg>) { - if let hir::TyKind::BareFn(hir::BareFnTy { param_idents, .. }) = &ty.kind { + if let hir::TyKind::FnPtr(hir::FnPtrTy { param_idents, .. }) = &ty.kind { for param_ident in *param_idents { if let Some(param_ident) = param_ident { self.check_snake_case(cx, "variable", param_ident); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index ea5485d8e5da7..e41bc8f852e58 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1577,7 +1577,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> { fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) { debug!(?ty); - if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind + if let hir::TyKind::FnPtr(hir::FnPtrTy { abi, .. }) = ty.kind && !abi.is_rustic_abi() { self.spans.push(ty.span); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0627f70507c45..d3942a1c81632 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1312,7 +1312,7 @@ impl EarlyLintPass for UnusedParens { None => true, } } - ast::TyKind::BareFn(b) => { + ast::TyKind::FnPtr(b) => { !self.with_self_ty_parens || b.generic_params.is_empty() } _ => true, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 1df0ccbd8af76..e0f810d8c1e3f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1677,7 +1677,7 @@ impl<'a> Parser<'a> { let hi = self.prev_token.span.shrink_to_hi(); BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } } } - TyKind::Ptr(..) | TyKind::BareFn(..) => { + TyKind::Ptr(..) | TyKind::FnPtr(..) => { BadTypePlusSub::ForgotParen { span: ty.span.to(self.prev_token.span) } } _ => BadTypePlusSub::ExpectPath { span: ty.span }, diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0c57a8cc5e1a5..a997be3405d69 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,7 +2,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, + self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy, @@ -283,14 +283,14 @@ impl<'a> Parser<'a> { TyKind::Infer } else if self.check_fn_front_matter(false, Case::Sensitive) { // Function pointer type - self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)? + self.parse_ty_fn_ptr(lo, ThinVec::new(), None, recover_return_sign)? } else if self.check_keyword(exp!(For)) { // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; if self.check_fn_front_matter(false, Case::Sensitive) { - self.parse_ty_bare_fn( + self.parse_ty_fn_ptr( lo, lifetime_defs, Some(self.prev_token.span.shrink_to_lo()), @@ -665,7 +665,7 @@ impl<'a> Parser<'a> { Ok(TyKind::Typeof(expr)) } - /// Parses a function pointer type (`TyKind::BareFn`). + /// Parses a function pointer type (`TyKind::FnPtr`). /// ```ignore (illustrative) /// [unsafe] [extern "ABI"] fn (S) -> T /// // ^~~~~^ ^~~~^ ^~^ ^ @@ -674,7 +674,7 @@ impl<'a> Parser<'a> { /// // Function Style ABI Parameter types /// ``` /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers. - fn parse_ty_bare_fn( + fn parse_ty_fn_ptr( &mut self, lo: Span, mut params: ThinVec, @@ -698,7 +698,7 @@ impl<'a> Parser<'a> { let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?; let decl_span = span_start.to(self.prev_token.span); - Ok(TyKind::BareFn(P(BareFnTy { ext, safety, generic_params: params, decl, decl_span }))) + Ok(TyKind::FnPtr(P(FnPtrTy { ext, safety, generic_params: params, decl, decl_span }))) } /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`). diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8fdc06ee463ad..67b68e77d2b72 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -267,6 +267,42 @@ pub fn check_builtin_meta_item( deny_unsafety: bool, ) { if !is_attr_template_compatible(&template, &meta.kind) { + // attrs with new parsers are locally validated so excluded here + if matches!( + name, + sym::inline + | sym::may_dangle + | sym::rustc_as_ptr + | sym::rustc_pub_transparent + | sym::rustc_const_stable_indirect + | sym::rustc_force_inline + | sym::rustc_confusables + | sym::rustc_skip_during_method_dispatch + | sym::rustc_pass_by_value + | sym::repr + | sym::align + | sym::deprecated + | sym::optimize + | sym::cold + | sym::target_feature + | sym::rustc_allow_const_fn_unstable + | sym::naked + | sym::no_mangle + | sym::non_exhaustive + | sym::path + | sym::ignore + | sym::must_use + | sym::track_caller + | sym::link_name + | sym::export_name + | sym::rustc_macro_transparency + | sym::link_section + | sym::rustc_layout_scalar_valid_range_start + | sym::rustc_layout_scalar_valid_range_end + | sym::no_implicit_prelude + ) { + return; + } emit_malformed_attribute(psess, style, meta.span, name, template); } @@ -282,42 +318,6 @@ fn emit_malformed_attribute( name: Symbol, template: AttributeTemplate, ) { - // attrs with new parsers are locally validated so excluded here - if matches!( - name, - sym::inline - | sym::may_dangle - | sym::rustc_as_ptr - | sym::rustc_pub_transparent - | sym::rustc_const_stable_indirect - | sym::rustc_force_inline - | sym::rustc_confusables - | sym::rustc_skip_during_method_dispatch - | sym::rustc_pass_by_value - | sym::repr - | sym::align - | sym::deprecated - | sym::optimize - | sym::cold - | sym::target_feature - | sym::rustc_allow_const_fn_unstable - | sym::naked - | sym::no_mangle - | sym::non_exhaustive - | sym::ignore - | sym::must_use - | sym::track_caller - | sym::link_name - | sym::export_name - | sym::rustc_macro_transparency - | sym::link_section - | sym::rustc_layout_scalar_valid_range_start - | sym::rustc_layout_scalar_valid_range_end - | sym::no_implicit_prelude - ) { - return; - } - // Some of previously accepted forms were used in practice, // report them as warnings for now. let should_warn = |name| matches!(name, sym::doc | sym::link | sym::test | sym::bench); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 5a94d01e08866..46c21dcf67b19 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -13,6 +13,10 @@ passes_abi_ne = passes_abi_of = fn_abi_of({$fn_name}) = {$fn_abi} +passes_align_attr_application = + `#[align(...)]` should be applied to a function item + .label = not a function item + passes_align_should_be_repr_align = `#[align(...)]` is not supported on {$item} items .suggestion = use `#[repr(align(...))]` instead diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3fa5cdc36bce9..9e4e78c1db68e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -191,6 +191,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target, Target::Mod, ), + Attribute::Parsed(AttributeKind::Path(_, attr_span)) => { + self.check_generic_attr(hir_id, sym::path, *attr_span, target, Target::Mod) + } Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => { self.check_track_caller(hir_id, *attr_span, attrs, span, target) } @@ -1915,7 +1918,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks if the `#[align]` attributes on `item` are valid. fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) { match target { - Target::Fn | Target::Method(_) => {} + Target::Fn | Target::Method(_) | Target::ForeignFn => {} Target::Struct | Target::Union | Target::Enum => { self.dcx().emit_err(errors::AlignShouldBeReprAlign { span: repr_span, @@ -1924,10 +1927,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }); } _ => { - self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { - hint_span: repr_span, - span, - }); + self.dcx().emit_err(errors::AlignAttrApplication { hint_span: repr_span, span }); } } @@ -2800,7 +2800,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { // resolution for the attribute macro error. const ATTRS_TO_CHECK: &[Symbol] = &[ sym::macro_export, - sym::path, sym::automatically_derived, sym::rustc_main, sym::derive, @@ -2822,6 +2821,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { }) = attr { (*first_attr_span, sym::repr) + } else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr { + (*span, sym::path) } else { continue; }; @@ -2946,8 +2947,8 @@ fn check_duplicates( fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool { matches!(&self_ty.kind, hir::TyKind::Tup([_])) - || if let hir::TyKind::BareFn(bare_fn_ty) = &self_ty.kind { - bare_fn_ty.decl.inputs.len() == 1 + || if let hir::TyKind::FnPtr(fn_ptr_ty) = &self_ty.kind { + fn_ptr_ty.decl.inputs.len() == 1 } else { false } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3ede3c889c8a1..4ad615a2abfc8 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1838,3 +1838,12 @@ pub(crate) struct AlignShouldBeReprAlign { pub item: &'static str, pub align_bytes: u64, } + +#[derive(Diagnostic)] +#[diag(passes_align_attr_application)] +pub(crate) struct AlignAttrApplication { + #[primary_span] + pub hint_span: Span, + #[label] + pub span: Span, +} diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 40bc18939d636..e38c7b2cbf15c 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -400,7 +400,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { Array, Ptr, Ref, - BareFn, + FnPtr, UnsafeBinder, Never, Tup, @@ -674,7 +674,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { Ptr, Ref, PinnedRef, - BareFn, + FnPtr, UnsafeBinder, Never, Tup, diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 56d9f5bf78577..a30655d32a7e5 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -1070,7 +1070,7 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> { if let TyKind::Never = t.kind { self.fully_stable = false; } - if let TyKind::BareFn(function) = t.kind { + if let TyKind::FnPtr(function) = t.kind { if extern_abi_stability(function.abi).is_err() { self.fully_stable = false; } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index a97e0eaa9c631..1238ce0125a1a 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -19,6 +19,7 @@ rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index eeb8cb893d75b..f775cac149e9e 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -18,6 +18,7 @@ use rustc_expand::base::ResolverExpand; use rustc_expand::expand::AstFragment; use rustc_hir::def::{self, *}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; +use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::LoadedMacro; use rustc_middle::metadata::ModChild; use rustc_middle::ty::Feed; @@ -1202,9 +1203,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) { if !ident.as_str().starts_with('_') { self.r.unused_macros.insert(def_id, (node_id, ident)); - for rule_i in 0..self.r.macro_map[&def_id.to_def_id()].nrules { - self.r.unused_macro_rules.entry(node_id).or_default().insert(rule_i); - } + let nrules = self.r.macro_map[&def_id.to_def_id()].nrules; + self.r.unused_macro_rules.insert(node_id, DenseBitSet::new_filled(nrules)); } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 08c4a485f2681..08629090bb109 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -370,7 +370,7 @@ enum LifetimeRibKind { #[derive(Copy, Clone, Debug)] enum LifetimeBinderKind { - BareFnType, + FnPtrType, PolyTrait, WhereBound, Item, @@ -384,7 +384,7 @@ impl LifetimeBinderKind { fn descr(self) -> &'static str { use LifetimeBinderKind::*; match self { - BareFnType => "type", + FnPtrType => "type", PolyTrait => "bound", WhereBound => "bound", Item | ConstItem => "item", @@ -900,16 +900,16 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc self.diag_metadata.current_trait_object = Some(&bounds[..]); visit::walk_ty(self, ty) } - TyKind::BareFn(bare_fn) => { - let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo()); + TyKind::FnPtr(fn_ptr) => { + let span = ty.span.shrink_to_lo().to(fn_ptr.decl_span.shrink_to_lo()); self.with_generic_param_rib( - &bare_fn.generic_params, + &fn_ptr.generic_params, RibKind::Normal, ty.id, - LifetimeBinderKind::BareFnType, + LifetimeBinderKind::FnPtrType, span, |this| { - this.visit_generic_params(&bare_fn.generic_params, false); + this.visit_generic_params(&fn_ptr.generic_params, false); this.with_lifetime_rib( LifetimeRibKind::AnonymousCreateParameter { binder: ty.id, @@ -921,12 +921,8 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc false, // We don't need to deal with patterns in parameters, because // they are not possible for foreign or bodiless functions. - bare_fn - .decl - .inputs - .iter() - .map(|Param { ty, .. }| (None, &**ty)), - &bare_fn.decl.output, + fn_ptr.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)), + &fn_ptr.decl.output, ) }, ); @@ -939,7 +935,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc &unsafe_binder.generic_params, RibKind::Normal, ty.id, - LifetimeBinderKind::BareFnType, + LifetimeBinderKind::FnPtrType, span, |this| { this.visit_generic_params(&unsafe_binder.generic_params, false); @@ -2976,7 +2972,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } - if let LifetimeBinderKind::BareFnType + if let LifetimeBinderKind::FnPtrType | LifetimeBinderKind::WhereBound | LifetimeBinderKind::Function | LifetimeBinderKind::ImplBlock = generics_kind diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a4022691995e7..fa04c8bc604b6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3177,7 +3177,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let higher_ranked = matches!( kind, - LifetimeBinderKind::BareFnType + LifetimeBinderKind::FnPtrType | LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound ); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3f865d7c2daca..f8ca20c568f13 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -57,6 +57,7 @@ use rustc_hir::def::{ use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate}; +use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; @@ -1135,7 +1136,7 @@ pub struct Resolver<'ra, 'tcx> { ast_transform_scopes: FxHashMap>, unused_macros: FxIndexMap, /// A map from the macro to all its potentially unused arms. - unused_macro_rules: FxIndexMap>, + unused_macro_rules: FxIndexMap>, proc_macro_stubs: FxHashSet, /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 9bc96403559ee..acbefe53422f7 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -334,7 +334,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { fn record_macro_rule_usage(&mut self, id: NodeId, rule_i: usize) { if let Some(rules) = self.unused_macro_rules.get_mut(&id) { - rules.remove(&rule_i); + rules.remove(rule_i); } } @@ -359,7 +359,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { let SyntaxExtensionKind::LegacyBang(ref ext) = m.ext.kind else { continue; }; - for &arm_i in unused_arms.to_sorted_stable_ord() { + for arm_i in unused_arms.iter() { if let Some((ident, rule_span)) = ext.get_unused_rule(arm_i) { self.lint_buffer.buffer_lint( UNUSED_MACRO_RULES, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 139b299713688..8fe4ffebd8655 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -75,7 +75,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result { match arg.kind { - hir::TyKind::BareFn(_) => { + hir::TyKind::FnPtr(_) => { self.current_index.shift_in(1); let _ = intravisit::walk_ty(self, arg); self.current_index.shift_out(1); diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index d03c1969b5b70..70c344e49b76a 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1031,7 +1031,7 @@ impl LinkedList { /// Retains only the elements specified by the predicate. /// - /// In other words, remove all elements `e` for which `f(&e)` returns false. + /// In other words, remove all elements `e` for which `f(&mut e)` returns false. /// This method operates in place, visiting each element exactly once in the /// original order, and preserves the order of the retained elements. /// @@ -1047,7 +1047,7 @@ impl LinkedList { /// d.push_front(2); /// d.push_front(3); /// - /// d.retain(|&x| x % 2 == 0); + /// d.retain(|&mut x| x % 2 == 0); /// /// assert_eq!(d.pop_front(), Some(2)); /// assert_eq!(d.pop_front(), None); @@ -1074,41 +1074,6 @@ impl LinkedList { /// ``` #[unstable(feature = "linked_list_retain", issue = "114135")] pub fn retain(&mut self, mut f: F) - where - F: FnMut(&T) -> bool, - { - self.retain_mut(|elem| f(elem)); - } - - /// Retains only the elements specified by the predicate. - /// - /// In other words, remove all elements `e` for which `f(&mut e)` returns false. - /// This method operates in place, visiting each element exactly once in the - /// original order, and preserves the order of the retained elements. - /// - /// # Examples - /// - /// ``` - /// #![feature(linked_list_retain)] - /// use std::collections::LinkedList; - /// - /// let mut d = LinkedList::new(); - /// - /// d.push_front(1); - /// d.push_front(2); - /// d.push_front(3); - /// - /// d.retain_mut(|x| if *x % 2 == 0 { - /// *x += 1; - /// true - /// } else { - /// false - /// }); - /// assert_eq!(d.pop_front(), Some(3)); - /// assert_eq!(d.pop_front(), None); - /// ``` - #[unstable(feature = "linked_list_retain", issue = "114135")] - pub fn retain_mut(&mut self, mut f: F) where F: FnMut(&mut T) -> bool, { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 9cadbd47ab6a5..ab6823249c3eb 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -786,12 +786,12 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(mixed_integer_ops_unsigned_sub)] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(2), None);")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(-2), Some(3));")] #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_sub_signed(-4), None);")] /// ``` - #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")] + #[stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1933,12 +1933,12 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(mixed_integer_ops_unsigned_sub)] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(2), 0);")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(-2), 3);")] #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).saturating_sub_signed(-4), ", stringify!($SelfT), "::MAX);")] /// ``` - #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")] + #[stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2081,12 +2081,12 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(mixed_integer_ops_unsigned_sub)] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(2), ", stringify!($SelfT), "::MAX);")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(-2), 3);")] #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).wrapping_sub_signed(-4), 1);")] /// ``` - #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")] + #[stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2540,12 +2540,12 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(mixed_integer_ops_unsigned_sub)] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(2), (", stringify!($SelfT), "::MAX, true));")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(-2), (3, false));")] #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_sub_signed(-4), (1, true));")] /// ``` - #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")] + #[stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "mixed_integer_ops_unsigned_sub", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index f55bdfeb3540d..2c77c55745b46 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -304,14 +304,12 @@ mod prim_bool {} /// This is what is known as "never type fallback". /// /// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously -/// coerced to `()`, even when it would not infer `()` without the fallback. There are plans to -/// change it in the [2024 edition] (and possibly in all editions on a later date); see -/// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. +/// coerced to `()`, even when it would not infer `()` without the fallback. The fallback was changed +/// to `!` in the [2024 edition], and will be changed in all editions at a later date. /// /// [coercion site]: /// [`()`]: prim@unit -/// [fallback-ti]: -/// [2024 edition]: +/// [2024 edition]: /// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 8a6925a0e9a43..fe64132ff227d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -446,7 +446,7 @@ impl str { #[unstable(feature = "round_char_boundary", issue = "93743")] #[inline] pub fn ceil_char_boundary(&self, index: usize) -> usize { - if index > self.len() { + if index >= self.len() { self.len() } else { let upper_bound = Ord::min(index + 4, self.len()); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5cd5c434521c0..c2f3da18cd302 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1834,7 +1834,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T }; DynTrait(bounds, lifetime) } - TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))), + TyKind::FnPtr(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))), TyKind::UnsafeBinder(unsafe_binder_ty) => { UnsafeBinder(Box::new(clean_unsafe_binder_ty(unsafe_binder_ty, cx))) } @@ -2558,7 +2558,7 @@ fn clean_path_segment<'tcx>( } fn clean_bare_fn_ty<'tcx>( - bare_fn: &hir::BareFnTy<'tcx>, + bare_fn: &hir::FnPtrTy<'tcx>, cx: &mut DocContext<'tcx>, ) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 7463d7b5c3bda..5099df3fa0239 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -824,7 +824,7 @@ impl TyCoercionStability { TyKind::Slice(_) | TyKind::Array(..) | TyKind::Ptr(_) - | TyKind::BareFn(_) + | TyKind::FnPtr(_) | TyKind::Pat(..) | TyKind::Never | TyKind::Tup(_) diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 8fe0c9d60f961..caf17c10484ff 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -13,7 +13,7 @@ use rustc_hir::intravisit::{ walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_unambig_ty, walk_where_predicate, }; use rustc_hir::{ - AmbigArg, BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, + AmbigArg, BodyId, FnDecl, FnPtrTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeKind, LifetimeParamKind, Node, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate, WherePredicateKind, lang_items, @@ -480,7 +480,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> { fn visit_ty(&mut self, ty: &'tcx Ty<'_, AmbigArg>) { match ty.kind { - TyKind::BareFn(&BareFnTy { decl, .. }) => { + TyKind::FnPtr(&FnPtrTy { decl, .. }) => { let mut sub_visitor = RefVisitor::new(self.cx); sub_visitor.visit_fn_decl(decl); self.nested_elision_site_lts.append(&mut sub_visitor.all_lts()); diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs index 0704653385f18..52c6fda80973c 100644 --- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs @@ -50,7 +50,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1), // function types bring a lot of overhead - TyKind::BareFn(bare) if bare.abi == ExternAbi::Rust => (50 * self.nest, 1), + TyKind::FnPtr(fn_ptr) if fn_ptr.abi == ExternAbi::Rust => (50 * self.nest, 1), TyKind::TraitObject(param_bounds, _) => { let has_lifetime_parameters = param_bounds.iter().any(|bound| { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index e6396987cc6d9..42254ec8e92d1 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -838,7 +838,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (PinnedRef(ll, l), PinnedRef(rl, r)) => { both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) }, - (BareFn(l), BareFn(r)) => { + (FnPtr(l), FnPtr(r)) => { l.safety == r.safety && eq_ext(&l.ext, &r.ext) && over(&l.generic_params, &r.generic_params, eq_generic_param) diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 407e92d88fb0a..ce61fffe0def0 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -372,17 +372,17 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")), TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1), TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), - TyKind::BareFn(bare_fn) => ( - if bare_fn.safety.is_unsafe() { + TyKind::FnPtr(fn_ptr) => ( + if fn_ptr.safety.is_unsafe() { Pat::Str("unsafe") - } else if bare_fn.abi != ExternAbi::Rust { + } else if fn_ptr.abi != ExternAbi::Rust { Pat::Str("extern") } else { Pat::MultiStr(&["fn", "extern"]) }, - match bare_fn.decl.output { + match fn_ptr.decl.output { FnRetTy::DefaultReturn(_) => { - if let [.., ty] = bare_fn.decl.inputs { + if let [.., ty] = fn_ptr.decl.inputs { ty_search_pat(ty).1 } else { Pat::Str("(") diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c37231d093129..0ca494f16e31d 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1283,20 +1283,20 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_ty(mut_ty.ty); mut_ty.mutbl.hash(&mut self.s); }, - TyKind::BareFn(bfn) => { - bfn.safety.hash(&mut self.s); - bfn.abi.hash(&mut self.s); - for arg in bfn.decl.inputs { + TyKind::FnPtr(fn_ptr) => { + fn_ptr.safety.hash(&mut self.s); + fn_ptr.abi.hash(&mut self.s); + for arg in fn_ptr.decl.inputs { self.hash_ty(arg); } - std::mem::discriminant(&bfn.decl.output).hash(&mut self.s); - match bfn.decl.output { + std::mem::discriminant(&fn_ptr.decl.output).hash(&mut self.s); + match fn_ptr.decl.output { FnRetTy::DefaultReturn(_) => {}, FnRetTy::Return(ty) => { self.hash_ty(ty); }, } - bfn.decl.c_variadic.hash(&mut self.s); + fn_ptr.decl.c_variadic.hash(&mut self.s); }, TyKind::Tup(ty_list) => { for ty in *ty_list { diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index c0df01edd6dee..9ee10d8627030 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1009,7 +1009,7 @@ impl Rewrite for ast::Ty { }) } } - ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape), + ast::TyKind::FnPtr(ref fn_ptr) => rewrite_fn_ptr(fn_ptr, self.span, context, shape), ast::TyKind::Never => Ok(String::from("!")), ast::TyKind::MacCall(ref mac) => { rewrite_macro(mac, context, shape, MacroPosition::Expression) @@ -1105,8 +1105,8 @@ impl Rewrite for ast::TyPat { } } -fn rewrite_bare_fn( - bare_fn: &ast::BareFnTy, +fn rewrite_fn_ptr( + fn_ptr: &ast::FnPtrTy, span: Span, context: &RewriteContext<'_>, shape: Shape, @@ -1115,7 +1115,7 @@ fn rewrite_bare_fn( let mut result = String::with_capacity(128); - if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &bare_fn.generic_params) { + if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &fn_ptr.generic_params) { result.push_str("for<"); // 6 = "for<> ".len(), 4 = "for<". // This doesn't work out so nicely for multiline situation with lots of @@ -1124,10 +1124,10 @@ fn rewrite_bare_fn( result.push_str("> "); } - result.push_str(crate::utils::format_safety(bare_fn.safety)); + result.push_str(crate::utils::format_safety(fn_ptr.safety)); result.push_str(&format_extern( - bare_fn.ext, + fn_ptr.ext, context.config.force_explicit_abi(), )); @@ -1145,9 +1145,9 @@ fn rewrite_bare_fn( }; let rewrite = format_function_type( - bare_fn.decl.inputs.iter(), - &bare_fn.decl.output, - bare_fn.decl.c_variadic(), + fn_ptr.decl.inputs.iter(), + &fn_ptr.decl.output, + fn_ptr.decl.c_variadic(), span, context, func_ty_shape, diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs index 5f114246ad557..77547e82041fe 100644 --- a/tests/assembly/naked-functions/wasm32.rs +++ b/tests/assembly/naked-functions/wasm32.rs @@ -27,18 +27,16 @@ extern "C" fn nop() { naked_asm!("nop") } -// CHECK: .section .text.weak_aligned_nop,"",@ -// CHECK: .weak weak_aligned_nop +// CHECK: .section .text.weak_nop,"",@ +// CHECK: .weak weak_nop // CHECK-LABEL: nop: -// CHECK: .functype weak_aligned_nop () -> () +// CHECK: .functype weak_nop () -> () // CHECK-NOT: .size // CHECK: end_function #[no_mangle] #[unsafe(naked)] #[linkage = "weak"] -// wasm functions cannot be aligned, so this has no effect -#[align(32)] -extern "C" fn weak_aligned_nop() { +extern "C" fn weak_nop() { naked_asm!("nop") } diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index 90073ff308143..fd572910c287f 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -1,4 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code +//@ edition: 2024 +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] @@ -116,3 +118,24 @@ pub fn align_specified_twice_2() {} #[align(32)] #[align(256)] pub fn align_specified_twice_3() {} + +const _: () = { + // CHECK-LABEL: align_unmangled + // CHECK-SAME: align 256 + #[unsafe(no_mangle)] + #[align(32)] + #[align(256)] + extern "C" fn align_unmangled() {} +}; + +unsafe extern "C" { + #[align(256)] + fn align_unmangled(); +} + +// FIXME also check `gen` et al +// CHECK-LABEL: async_align +// CHECK-SAME: align 64 +#[unsafe(no_mangle)] +#[align(64)] +pub async fn async_align() {} diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs index 78989ec5df236..6a3843b0f4f59 100644 --- a/tests/codegen/min-function-alignment.rs +++ b/tests/codegen/min-function-alignment.rs @@ -2,6 +2,7 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code //@ [align16] compile-flags: -Zmin-function-alignment=16 //@ [align1024] compile-flags: -Zmin-function-alignment=1024 +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs index f9fce8e5a5d59..2648b0213ca86 100644 --- a/tests/codegen/naked-fn/aligned.rs +++ b/tests/codegen/naked-fn/aligned.rs @@ -1,6 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 //@ needs-asm-support //@ ignore-arm no "ret" mnemonic +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs index 59554c1cae554..4ebaacd3eff79 100644 --- a/tests/codegen/naked-fn/min-function-alignment.rs +++ b/tests/codegen/naked-fn/min-function-alignment.rs @@ -1,6 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16 //@ needs-asm-support //@ ignore-arm no "ret" mnemonic +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![feature(fn_align)] #![crate_type = "lib"] diff --git a/tests/ui/attributes/fn-align-dyn.rs b/tests/ui/attributes/fn-align-dyn.rs new file mode 100644 index 0000000000000..8ba4d5e2897df --- /dev/null +++ b/tests/ui/attributes/fn-align-dyn.rs @@ -0,0 +1,16 @@ +//@ run-pass +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) +#![feature(fn_align)] + +trait Test { + #[align(4096)] + fn foo(&self); + + #[align(4096)] + fn foo1(&self); +} + +fn main() { + assert_eq!((::foo as fn(_) as usize & !1) % 4096, 0); + assert_eq!((::foo1 as fn(_) as usize & !1) % 4096, 0); +} diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index f5ab9555e561f..e06e611684242 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -21,5 +21,29 @@ fn f3() {} #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items fn f4() {} +#[align(-1)] //~ ERROR expected unsuffixed literal, found `-` +fn f5() {} + +#[align(3)] //~ ERROR invalid alignment value: not a power of two +fn f6() {} + +#[align(4usize)] //~ ERROR invalid alignment value: not an unsuffixed integer [E0589] +//~^ ERROR suffixed literals are not allowed in attributes +fn f7() {} + +#[align(16)] +#[align(3)] //~ ERROR invalid alignment value: not a power of two +#[align(16)] +fn f8() {} + #[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items struct S1; + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +const FOO: i32 = 42; + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +mod test {} + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +use ::std::iter; diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index b769d0b457ddd..af3625b1f3b9e 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -1,3 +1,17 @@ +error: expected unsuffixed literal, found `-` + --> $DIR/malformed-fn-align.rs:24:9 + | +LL | #[align(-1)] + | ^ + +error: suffixed literals are not allowed in attributes + --> $DIR/malformed-fn-align.rs:30:9 + | +LL | #[align(4usize)] + | ^^^^^^ + | + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) + error[E0539]: malformed `align` attribute input --> $DIR/malformed-fn-align.rs:5:5 | @@ -37,6 +51,24 @@ error[E0589]: invalid alignment value: not a power of two LL | #[align(0)] | ^ +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-fn-align.rs:27:9 + | +LL | #[align(3)] + | ^ + +error[E0589]: invalid alignment value: not an unsuffixed integer + --> $DIR/malformed-fn-align.rs:30:9 + | +LL | #[align(4usize)] + | ^^^^^^ + +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-fn-align.rs:35:9 + | +LL | #[align(3)] + | ^ + error: `#[repr(align(...))]` is not supported on function items --> $DIR/malformed-fn-align.rs:21:8 | @@ -50,7 +82,7 @@ LL | #[repr(align(16))] | ^^^^^^^^^ error: `#[align(...)]` is not supported on struct items - --> $DIR/malformed-fn-align.rs:24:1 + --> $DIR/malformed-fn-align.rs:39:1 | LL | #[align(16)] | ^^^^^^^^^^^^ @@ -61,7 +93,31 @@ LL - #[align(16)] LL + #[repr(align(16))] | -error: aborting due to 7 previous errors +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:42:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | const FOO: i32 = 42; + | -------------------- not a function item + +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:45:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | mod test {} + | ----------- not a function item + +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:48:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | use ::std::iter; + | ---------------- not a function item + +error: aborting due to 15 previous errors Some errors have detailed explanations: E0539, E0589, E0805. For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 1620bf7292293..49c666f498f58 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -121,21 +121,6 @@ LL - #![rustc_main] LL + #[rustc_main] | -error: `path` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 - | -LL | #![path = "3800"] - | ^^^^^^^^^^^^^^^^^ -... -LL | mod inline { - | ------ the inner attribute doesn't annotate this module - | -help: perhaps you meant to use an outer attribute - | -LL - #![path = "3800"] -LL + #[path = "3800"] - | - error: `automatically_derived` attribute cannot be used at crate level --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1 | @@ -166,6 +151,21 @@ LL - #![repr()] LL + #[repr()] | +error: `path` attribute cannot be used at crate level + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 + | +LL | #![path = "3800"] + | ^^^^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module + | +help: perhaps you meant to use an outer attribute + | +LL - #![path = "3800"] +LL + #[path = "3800"] + | + error[E0518]: attribute should be applied to function or closure --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:42:17 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 275eb05630520..2310c12c80b56 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -27,19 +27,6 @@ note: attribute also specified here LL | #[macro_use] | ^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:47:1 - | -LL | #[path = "bar.rs"] - | ^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:46:1 - | -LL | #[path = "auxiliary/lint_unused_extern_crate.rs"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - error: unused attribute --> $DIR/unused-attr-duplicate.rs:55:1 | @@ -153,6 +140,19 @@ note: attribute also specified here LL | #[macro_export] | ^^^^^^^^^^^^^^^ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:47:1 + | +LL | #[path = "bar.rs"] + | ^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:46:1 + | +LL | #[path = "auxiliary/lint_unused_extern_crate.rs"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + error: unused attribute --> $DIR/unused-attr-duplicate.rs:53:1 | diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr index e3ca90d9acdd0..4698e38142588 100644 --- a/tests/ui/lint/unused/unused-attr-macro-rules.stderr +++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr @@ -10,17 +10,17 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: `#[path]` only has an effect on modules - --> $DIR/unused-attr-macro-rules.rs:8:1 - | -LL | #[path="foo"] - | ^^^^^^^^^^^^^ - error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` --> $DIR/unused-attr-macro-rules.rs:9:1 | LL | #[recursion_limit="1"] | ^^^^^^^^^^^^^^^^^^^^^^ +error: `#[path]` only has an effect on modules + --> $DIR/unused-attr-macro-rules.rs:8:1 + | +LL | #[path="foo"] + | ^^^^^^^^^^^^^ + error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/path-attr-in-const-block.rs b/tests/ui/resolve/path-attr-in-const-block.rs index 076511d26d6d3..69be65bda3f8b 100644 --- a/tests/ui/resolve/path-attr-in-const-block.rs +++ b/tests/ui/resolve/path-attr-in-const-block.rs @@ -5,5 +5,6 @@ fn main() { const { #![path = foo!()] //~^ ERROR: cannot find macro `foo` in this scope + //~| ERROR malformed `path` attribute input } } diff --git a/tests/ui/resolve/path-attr-in-const-block.stderr b/tests/ui/resolve/path-attr-in-const-block.stderr index 8f9e58157c809..0b5942a287d03 100644 --- a/tests/ui/resolve/path-attr-in-const-block.stderr +++ b/tests/ui/resolve/path-attr-in-const-block.stderr @@ -4,5 +4,15 @@ error: cannot find macro `foo` in this scope LL | #![path = foo!()] | ^^^ -error: aborting due to 1 previous error +error[E0539]: malformed `path` attribute input + --> $DIR/path-attr-in-const-block.rs:6:9 + | +LL | #![path = foo!()] + | ^^^^^^^^^^------^ + | | | + | | expected a string literal here + | help: must be of the form: `#[path = "file"]` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0539`.