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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3074,7 +3074,7 @@ impl FnDecl {
} else {
arg.attrs
.iter()
.any(|attr| attr.has_name(sym::splat))
.any(|attr| attr.has_name(sym::rustc_splat))
.then_some(u8::try_from(index).unwrap())
}
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id())
}

/// Returns function parameter info, including C variadic `...` and `#[splat]` if present.
/// Returns function parameter info, including C variadic `...` and `#[rustc_splat]` if present.
fn param_info(&self, def_id: DefId) -> ParamInfo {
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ impl<'a> AstValidator<'a> {

/// Emits an error if a function declaration has more than one splatted argument, with a
/// C-variadic parameter, or a splat at an unsupported index (for performance).
/// Example: `fn foo(#[splat] x: (), #[splat] y: ())` will emit an error.
/// Example: `fn foo(#[rustc_splat] x: (), #[rustc_splat] y: ())` will emit an error.
fn check_decl_splatting(&self, fn_decl: &FnDecl, c_variadic_span: Option<Span>) {
let (splatted_arg_indexes, mut splatted_spans): (Vec<u16>, Vec<Span>) = fn_decl
.inputs
Expand All @@ -407,7 +407,7 @@ impl<'a> AstValidator<'a> {
.filter_map(|(index, arg)| {
arg.attrs
.iter()
.any(|attr| attr.has_name(sym::splat))
.any(|attr| attr.has_name(sym::rustc_splat))
.then_some((u16::try_from(index).unwrap(), arg.span))
})
.unzip();
Expand Down Expand Up @@ -451,7 +451,7 @@ impl<'a> AstValidator<'a> {
sym::deny,
sym::expect,
sym::forbid,
sym::splat,
sym::rustc_splat,
sym::warn,
];
!attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(*attr)
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_ast_passes/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,27 +124,27 @@ pub(crate) struct FnParamCVarArgsNotLast {
}

#[derive(Diagnostic)]
#[diag("`#[splat]` is not supported on argument index {$splatted_arg_index}")]
#[help("remove `#[splat]`, or use it on an argument closer to the start of the argument list")]
#[diag("`#[rustc_splat]` is not supported on argument index {$splatted_arg_index}")]
#[help("remove `#[rustc_splat]`, or use it on an argument closer to the start of the argument list")]
pub(crate) struct InvalidSplattedArg {
pub splatted_arg_index: u16,

#[primary_span]
#[label("`#[splat]` is not supported here")]
#[label("`#[rustc_splat]` is not supported here")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("multiple `#[splat]`s are not allowed in the same function")]
#[help("remove `#[splat]` from all but one argument")]
#[diag("multiple `#[rustc_splat]`s are not allowed in the same function")]
#[help("remove `#[rustc_splat]` from all but one argument")]
pub(crate) struct DuplicateSplattedArgs {
#[primary_span]
pub spans: Vec<Span>,
}

#[derive(Diagnostic)]
#[diag("`...` and `#[splat]` are not allowed in the same function")]
#[help("remove `#[splat]` or remove `...`")]
#[diag("`...` and `#[rustc_splat]` are not allowed in the same function")]
#[help("remove `#[rustc_splat]` or remove `...`")]
pub(crate) struct CVarArgsAndSplat {
#[primary_span]
pub spans: Vec<Span>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
gate_all!(postfix_match, "postfix match is experimental");
gate_all!(return_type_notation, "return type notation is experimental");
gate_all!(splat, "`fn(#[splat] (a, ...))` is incomplete", "call as func((a, ...)) instead");
gate_all!(splat, "`fn(#[rustc_splat] (a, ...))` is incomplete", "call as func((a, ...)) instead");
gate_all!(super_let, "`super let` is experimental");
gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental");
gate_all!(unnamed_enum_variants, "unnamed enum variants are experimental");
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/splat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Attribute parsing for the `#[splat]` function argument overloading attribute.
//! Attribute parsing for the `#[rustc_splat]` function argument overloading attribute.
//! This attribute modifies typecheck to support overload resolution, then modifies codegen for performance.

use rustc_feature::AttributeStability;
Expand All @@ -8,9 +8,9 @@ use super::prelude::*;
pub(crate) struct SplatParser;

impl NoArgsAttributeParser for SplatParser {
const PATH: &[Symbol] = &[sym::splat];
const PATH: &[Symbol] = &[sym::rustc_splat];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Param)]);
const STABILITY: AttributeStability =
unstable!(splat, "the `#[splat]` attribute is experimental");
unstable!(splat, "the `#[rustc_splat]` attribute is experimental");
const CREATE: fn(Span) -> AttributeKind = AttributeKind::Splat;
}
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/unroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use super::prelude::*;

pub(crate) struct UnrollParser;
impl SingleAttributeParser for UnrollParser {
const PATH: &[Symbol] = &[sym::unroll];
// FIXME(#159429): temporarily renamed to mitigate `#[unroll]` nameres ambiguity.
const PATH: &[Symbol] = &[sym::rustc_unroll];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
Allow(Target::Loop),
Allow(Target::ForLoop),
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,18 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[
// - https://github.com/rust-lang/rust/issues/130494
sym::pin_v2,

// The `#[splat]` attribute is part of the `splat` experiment
// The `#[rustc_splat]` attribute is part of the `splat` experiment
// that improves the ergonomics of function overloading, tracked in:
//
// - https://github.com/rust-lang/rust/issues/153629
sym::splat,
sym::rustc_splat,

// The `#[unroll]` attribute.
// The `#[rustc_unroll]` attribute.
//
// - https://github.com/rust-lang/rust/pull/156816
sym::unroll,
//
// FIXME(#159429): temporarily renamed to mitigate `#[unroll]` nameres ambiguity
sym::rustc_unroll,

// `#[instrument_fn = "on|off"]` to insert or inhibit instrumentation function
// calls inside a function, usually around the prologue.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ declare_features! (
/// Allows specialization of implementations (RFC 1210).
(incomplete, specialization, "1.7.0", Some(31844)),
/// Experimental "splatting" of function call arguments at the call site.
/// e.g. `foo(a, b, c)` calls `#[splat] fn foo((a: A, b: B, c: C))`.
/// e.g. `foo(a, b, c)` calls `#[rustc_splat] fn foo((a: A, b: B, c: C))`.
(incomplete, splat, "1.98.0", Some(153629)),
/// Allows using `#[rustc_align_static(...)]` on static items.
(unstable, static_align, "1.91.0", Some(146177)),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,7 @@ pub enum AttributeKind {
reason: Option<Symbol>,
},

/// Represents `#[splat]`
/// Represents `#[rustc_splat]`
Splat(Span),

/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
Expand Down Expand Up @@ -1697,7 +1697,8 @@ pub enum AttributeKind {
limit: Limit,
},

/// Represents `#[unroll]`
/// Represents `#[rustc_unroll]`
// FIXME(#159429): temporarily renamed from `#[unroll]` to mitigate nameres ambiguity
Unroll(UnrollAttr),

/// Represents `#[unstable_feature_bound]`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ fn fn_sig_suggestion<'tcx>(
.iter()
.enumerate()
.map(|(i, ty)| {
let splat = if splatted_arg_index == Some(i) { "#[splat] " } else { "" };
let splat = if splatted_arg_index == Some(i) { "#[rustc_splat] " } else { "" };
let arg_ty = match ty.kind() {
ty::Param(_) if assoc.is_method() && i == 0 => "self".to_string(),
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,7 @@ impl<'a> State<'a> {
let mut i = 0;
let mut print_arg = |s: &mut Self, ty: Option<&hir::Ty<'_>>| {
if Some(i) == decl.splatted().map(usize::from) {
s.word("#[splat]");
s.word("#[rustc_splat]");
}
if i == 0 && decl.implicit_self().has_implicit_self() {
s.print_implicit_self(&decl.implicit_self());
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ rustc_index::newtype_index! {
pub(crate) struct GenericIdx {}
}

/// Outcome of checking arguments that are tupled by "rust-call" or `#[splat]`.
/// Outcome of checking arguments that are tupled by "rust-call" or `#[rustc_splat]`.
#[derive(Debug, Clone, Eq, PartialEq)]
struct TupledArgCheckOutcome<'tcx> {
/// The error code to emit if the arguments are not compatible.
Expand Down Expand Up @@ -560,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// Check arguments that are tupled by "rust-call" or `#[splat]`.
/// Check arguments that are tupled by "rust-call" or `#[rustc_splat]`.
fn check_tupled_arguments(
&self,
// Span enclosing the call site
Expand Down Expand Up @@ -596,10 +596,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// The argument difference can range from -1 to u16::MAX - 1, so we count the number
// of tupled arguments instead.
// (An empty argument list becomes a unit tuple in the callee.)
// 0: f() -> f(#[splat] _: ())
// 1: f(a) -> f(#[splat] _: (A,))
// 2: f(a, b) -> f(#[splat] _: (A, B))
// The Fn* traits ensure this by construction, and `#[splat]` can only be applied to
// 0: f() -> f(#[rustc_splat] _: ())
// 1: f(a) -> f(#[rustc_splat] _: (A,))
// 2: f(a, b) -> f(#[rustc_splat] _: (A, B))
// The Fn* traits ensure this by construction, and `#[rustc_splat]` can only be applied to
// an actual argument.
let tupled_args_count = (1 + provided_args.len()).checked_sub(formal_input_tys.len());
debug!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
let mut input_iter = inputs.iter().copied();
if let Some(index) = splatted_arg_index {
self.comma_sep((&mut input_iter).take(usize::from(index)))?;
write!(self, ", #[splat]")?;
write!(self, ", #[rustc_splat]")?;
self.comma_sep(input_iter)?;
} else {
self.comma_sep(input_iter)?;
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
hir::ExprKind::MethodCall(segment, receiver, args, fn_span) => {
if self.typeck_results.is_splatted_call(expr) {
// The callee has a splatted tuple argument.
// rewrite `receiver.f(a, u, v)` into `receiver.f(a, #[splat] (u, v))`
// rewrite `receiver.f(a, u, v)` into `receiver.f(a, #[rustc_splat] (u, v))`
self.convert_splatted_callee(expr, fn_span, args, Some(receiver))
} else {
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
Expand Down Expand Up @@ -421,7 +421,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
} else if self.typeck_results.is_splatted_call(expr) {
// The callee has a splatted tuple argument.
// rewrite `f(a, u, v)` into `f(a, #[splat] (u, v))`
// rewrite `f(a, u, v)` into `f(a, #[rustc_splat] (u, v))`
self.convert_splatted_callee(expr, fun.span, args, None)
} else {
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
Expand Down Expand Up @@ -1248,7 +1248,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}

/// The callee has a splatted tuple argument.
/// Rewrite a splatted call `receiver.f(a, u, v)` into `receiver.f(a, #[splat] (u, v))`.
/// Rewrite a splatted call `receiver.f(a, u, v)` into `receiver.f(a, #[rustc_splat] (u, v))`.
/// The receiver is optional.
fn convert_splatted_callee(
&mut self,
Expand All @@ -1264,7 +1264,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let tupled_arg_index = usize::from(tupled_arg_index);
let tupled_args_count = usize::from(tupled_args_count);

// Splatting an empty tuple is permitted: `a.f() -> Trait::f(a, #[splat] ())`.
// Splatting an empty tuple is permitted: `a.f() -> Trait::f(a, #[rustc_splat] ())`.
// In that case, the tupled arg index is one past the end of the args.
if tupled_arg_index + tupled_args_count > args.len() {
span_bug!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_public/src/unstable/convert/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ impl RustcInternal for FnSig {
tables: &mut Tables<'_, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
// FIXME(splat): When `#[splat]` is complete (or stable), add splatted to the public FnSig
// FIXME(splat): When `#[rustc_splat]` is complete (or stable), add splatted to the public FnSig
let fn_sig_kind = rustc_ty::FnSigKind::default()
.set_abi(self.abi.internal(tables, tcx))
.set_safety(self.safety.internal(tables, tcx))
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1850,11 +1850,14 @@ symbols! {
rustc_simd_monomorphize_lane_limit,
rustc_skip_during_method_dispatch,
rustc_specialization_trait,
rustc_splat,
rustc_std_internal_symbol,
rustc_strict_coherence,
rustc_test_marker,
rustc_then_this_would_need,
rustc_trivial_field_reads,
// FIXME(#159429): temporary rename to avoid `#[unroll]` nameres ambiguity
rustc_unroll,
rustc_unsafe_specialization_marker,
rustdoc,
rustdoc_internals,
Expand Down Expand Up @@ -2235,7 +2238,6 @@ symbols! {
unreachable_display,
unreachable_macro,
unrestricted_attribute_tokens,
unroll,
unsafe_attributes,
unsafe_binders,
unsafe_block_in_unsafe_fn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -829,11 +829,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
for (i, (l, r)) in iter::zip(sig1.inputs(), sig2.inputs()).enumerate() {
self.push_comma(&mut values.0, &mut values.1, i);
if Some(i) == splatted_arg_index1 {
values.0.push("#[splat]", splatted_arg_index1 != splatted_arg_index2);
values.0.push("#[rustc_splat]", splatted_arg_index1 != splatted_arg_index2);
values.0.push_normal(" ");
}
if Some(i) == splatted_arg_index2 {
values.1.push("#[splat]", splatted_arg_index1 != splatted_arg_index2);
values.1.push("#[rustc_splat]", splatted_arg_index1 != splatted_arg_index2);
values.1.push_normal(" ");
}
let (x1, x2) = self.cmp(*l, *r);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1239,7 +1239,7 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
write!(f, ", ")?;
}
if Some(i) == fn_sig_kind.splatted().map(usize::from) {
write!(f, "#[splat] ")?;
write!(f, "#[rustc_splat] ")?;
}
write!(f, "{ty:?}")?;
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/mem/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ pub struct FnPtr {
pub is_splatted: bool,

/// The index of the splatted function argument in `inputs`, only valid if `is_splatted` is true.
/// e.g. in `fn overload(a: u8, #[splat] b: (f32, usize))` the index is 1, and it can be called
/// e.g. in `fn overload(a: u8, #[rustc_splat] b: (f32, usize))` the index is 1, and it can be called
/// as `overload(a, 1.0, 2)`.
pub splatted_index: u8,
}
Expand Down
2 changes: 1 addition & 1 deletion library/coretests/tests/mem/fn_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fn test_variadic() {
#[test]
fn test_splat() {
#[rustfmt::skip]
let TypeKind::FnPtr(fn_ptr_ty) = &(const { Type::of::<fn(#[splat] (String, u8))>().kind }) else {
let TypeKind::FnPtr(fn_ptr_ty) = &(const { Type::of::<fn(#[rustc_splat] (String, u8))>().kind }) else {
panic!();
};
let FnPtr {
Expand Down
12 changes: 8 additions & 4 deletions src/doc/unstable-book/src/language-features/loop-hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ The tracking issue for this feature is: [#156874]

------

<!--
FIXME(#159429): temporarily renamed `#[unroll]` to mitigate a nameres ambiguity
-->

Loop unrolling can be a powerful optimization but like inlining, it is sometimes useful to
manually provide hints to optimizations.

`#[unroll]` will encourage unrolling of a loop.
`#[rustc_unroll]` will encourage unrolling of a loop.

`#[unroll(full)]` is a stronger hint and can cause optimizations to completely ignore the code
`#[rustc_unroll(full)]` is a stronger hint and can cause optimizations to completely ignore the code
side growth from repeating a loop body.

`#[unroll(never)]` is a strong hint to not unroll the loop at all. Note that other loop
`#[rustc_unroll(never)]` is a strong hint to not unroll the loop at all. Note that other loop
optimizations may still be applied.

`#[unroll(N)]` is a hint to unroll `N` iterations of the loop.
`#[rustc_unroll(N)]` is a hint to unroll `N` iterations of the loop.

In all cases these are just hints and may be ignored. But unlike function inlining hints,
loops tend to be heavily modified during compilation, which can make obeying hints challenging.
Expand Down
Loading
Loading