Auto merge of #143556 - jhpratt:rollup-nid39y2, r=jhpratt
Rollup of 9 pull requests Successful merges: - rust-lang/rust#143206 (Align attr fixes) - rust-lang/rust#143236 (Stabilize `mixed_integer_ops_unsigned_sub`) - rust-lang/rust#143344 (Port `#[path]` to the new attribute parsing infrastructure ) - rust-lang/rust#143359 (Link to 2024 edition page for `!` fallback changes) - rust-lang/rust#143456 (mbe: Change `unused_macro_rules` to a `DenseBitSet`) - rust-lang/rust#143529 (Renamed retain_mut to retain on LinkedList as mentioned in the ACP) - rust-lang/rust#143535 (Remove duplicate word) - rust-lang/rust#143544 (compiler: rename BareFn to FnPtr) - rust-lang/rust#143552 (lib: more eagerly return `self.len()` from `ceil_char_boundary`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0d11be5aab
71 changed files with 405 additions and 272 deletions
|
|
@ -4474,6 +4474,7 @@ dependencies = [
|
|||
"rustc_feature",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_metadata",
|
||||
"rustc_middle",
|
||||
|
|
|
|||
|
|
@ -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<GenericParam>,
|
||||
|
|
@ -2455,8 +2455,8 @@ pub enum TyKind {
|
|||
///
|
||||
/// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
|
||||
PinnedRef(Option<Lifetime>, MutTy),
|
||||
/// A bare function (e.g., `fn(usize) -> bool`).
|
||||
BareFn(P<BareFnTy>),
|
||||
/// A function pointer type (e.g., `fn(usize) -> bool`).
|
||||
FnPtr(P<FnPtrTy>),
|
||||
/// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
|
||||
UnsafeBinder(P<UnsafeBinderTy>),
|
||||
/// The never type (`!`).
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ impl AttributeKind {
|
|||
NonExhaustive(..) => Yes,
|
||||
Optimize(..) => No,
|
||||
PassByValue(..) => Yes,
|
||||
Path(..) => No,
|
||||
PubTransparent(..) => Yes,
|
||||
Repr { .. } => No,
|
||||
RustcLayoutScalarValidRangeEnd(..) => Yes,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
29
compiler/rustc_attr_parsing/src/attributes/path.rs
Normal file
29
compiler/rustc_attr_parsing/src/attributes/path.rs
Normal file
|
|
@ -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<S: Stage> SingleAttributeParser<S> for PathParser {
|
||||
const PATH: &[Symbol] = &[sym::path];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "file");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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<LinkSectionParser>,
|
||||
Single<MustUseParser>,
|
||||
Single<OptimizeParser>,
|
||||
Single<PathAttributeParser>,
|
||||
Single<RustcForceInlineParser>,
|
||||
Single<RustcLayoutScalarValidRangeEnd>,
|
||||
Single<RustcLayoutScalarValidRangeStart>,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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<Ident>]` 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<Ident>], &'hir Generics<'hir>),
|
||||
/// A foreign static item (`static ext: u8`).
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
|||
type Result = ControlFlow<Span>;
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) -> ControlFlow<Span> {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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<LocalDefId, ResolvedArg>, 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(..), .. }) => {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
&[]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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<GenericParam>,
|
||||
|
|
@ -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)`).
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<LocalExpnId, Module<'ra>>,
|
||||
unused_macros: FxIndexMap<LocalDefId, (NodeId, Ident)>,
|
||||
/// A map from the macro to all its potentially unused arms.
|
||||
unused_macro_rules: FxIndexMap<NodeId, UnordSet<usize>>,
|
||||
unused_macro_rules: FxIndexMap<NodeId, DenseBitSet<usize>>,
|
||||
proc_macro_stubs: FxHashSet<LocalDefId>,
|
||||
/// Traces collected during macro resolution and validated when it's complete.
|
||||
single_segment_macro_resolutions:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1031,7 +1031,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
|
|||
|
||||
/// 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<T, A: Allocator> LinkedList<T, A> {
|
|||
/// 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<T, A: Allocator> LinkedList<T, A> {
|
|||
/// ```
|
||||
#[unstable(feature = "linked_list_retain", issue = "114135")]
|
||||
pub fn retain<F>(&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<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(&mut T) -> bool,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]: <https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites>
|
||||
/// [`()`]: prim@unit
|
||||
/// [fallback-ti]: <https://github.com/rust-lang/rust/issues/123748>
|
||||
/// [2024 edition]: <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html>
|
||||
/// [2024 edition]: <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
|
||||
///
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
mod prim_never {}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -824,7 +824,7 @@ impl TyCoercionStability {
|
|||
TyKind::Slice(_)
|
||||
| TyKind::Array(..)
|
||||
| TyKind::Ptr(_)
|
||||
| TyKind::BareFn(_)
|
||||
| TyKind::FnPtr(_)
|
||||
| TyKind::Pat(..)
|
||||
| TyKind::Never
|
||||
| TyKind::Tup(_)
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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("(")
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
16
tests/ui/attributes/fn-align-dyn.rs
Normal file
16
tests/ui/attributes/fn-align-dyn.rs
Normal file
|
|
@ -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!((<dyn Test>::foo as fn(_) as usize & !1) % 4096, 0);
|
||||
assert_eq!((<dyn Test>::foo1 as fn(_) as usize & !1) % 4096, 0);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ fn main() {
|
|||
const {
|
||||
#![path = foo!()]
|
||||
//~^ ERROR: cannot find macro `foo` in this scope
|
||||
//~| ERROR malformed `path` attribute input
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue