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_lowering/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const {
anon_const: self.lower_const_block(anon_const),
anon_const: self.lower_const_block(anon_const, &[]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can put at least some atributes on const operands. Iirc recently cfg was stabilized here? Though that one is of course expanded out early. Still wonder where those attributes go and whether they should be forwarded here 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if in this case it only matters for their stability attrs

},
InlineAsmOperand::Sym { sym } => {
let static_def_id = self
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ impl<'hir> LoweringContext<'_, 'hir> {

let kind = match &e.kind {
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
ExprKind::ConstBlock(c) => hir::ExprKind::ConstBlock(self.lower_const_block(c)),
ExprKind::ConstBlock(c) => {
hir::ExprKind::ConstBlock(self.lower_const_block(c, attrs))
}
ExprKind::Repeat(expr, count) => {
let expr = self.lower_expr(expr);
let count = self.lower_array_length_to_const_arg(count);
Expand Down Expand Up @@ -386,12 +388,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
})
}

pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock {
pub(crate) fn lower_const_block(
&mut self,
c: &AnonConst,
attrs: &'hir [hir::Attribute],
) -> hir::ConstBlock {
self.with_new_scopes(c.value.span, |this| {
let def_id = this.local_def_id(c.id);
let hir_id = this.lower_node_id(c.id);
if !attrs.is_empty() {
this.attrs.insert(hir_id.local_id, attrs);
}
hir::ConstBlock {
def_id,
hir_id: this.lower_node_id(c.id),
hir_id,
body: this.lower_const_body(c.value.span, Some(&c.value)),
}
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExprKind::Lit(lit) => {
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: false }
}
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)),
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c, &[])),
ExprKind::IncludedBytes(byte_sym) => hir::PatExprKind::Lit {
lit: respan(span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)),
negated: false,
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,21 @@ impl<S: Stage> AttributeParser<S> for ConstStabilityParser {
this.promotable = true;
}),
];
const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Use), // FIXME I don't think this does anything?
Allow(Target::Const),
Allow(Target::AssocConst),
Allow(Target::Trait),
Allow(Target::Static),
Allow(Target::Expression), // FIXME: we really only want to allow inline consts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could make up a new target for that 🤷‍♀️ . This would be its current only use but it's not that hard to do otherwise

Allow(Target::Crate),
]);

fn finalize(mut self, cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
if self.promotable {
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_const_eval/src/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn enforce_recursive_const_stability(&self) -> bool {
// We can skip this if neither `staged_api` nor `-Zforce-unstable-if-unmarked` are enabled,
// since in such crates `lookup_const_stability` will always be `None`.
self.const_kind == Some(hir::ConstContext::ConstFn)
&& (self.tcx.features().staged_api()
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
matches!(
self.const_kind,
Some(hir::ConstContext::ConstFn | hir::ConstContext::Const { inline: true })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a partial fix. I can remove the inline limitation here, but it has a lot of fallout that I haven't analyzed yet. I'll do that in a follow-up

) && (self.tcx.features().staged_api()
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
&& is_fn_or_trait_safe_to_expose_on_stable(self.tcx, self.def_id().to_def_id())
}

Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_expand/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ expand_macro_call_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for macro invocations
.help = to document an item produced by a macro, the macro must produce the documentation as part of its expansion

expand_macro_const_stability =
macros cannot have const stability attributes
.label = invalid const stability attribute
.label2 = const stability attribute affects this macro

expand_macro_expands_to_match_arm = macros cannot expand to match arms

expand_malformed_feature_attribute =
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,12 +979,6 @@ impl SyntaxExtension {
let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability);

// FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot what my own fixme here refers to tbh. I think it looks like its already handled? Could you remove it?

if let Some(sp) = find_attr!(attrs, AttributeKind::ConstStability { span, .. } => *span) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we removing this check from macros? Don't quite follow how its related to the rest of your PR

sess.dcx().emit_err(errors::MacroConstStability {
span: sp,
head_span: sess.source_map().guess_head_span(span),
});
}
if let Some(sp) = find_attr!(attrs, AttributeKind::BodyStability{ span, .. } => *span) {
sess.dcx().emit_err(errors::MacroBodyStability {
span: sp,
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_expand/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,6 @@ pub(crate) struct CollapseMacroDebuginfoIllegal {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(expand_macro_const_stability)]
pub(crate) struct MacroConstStability {
#[primary_span]
#[label]
pub span: Span,
#[label(expand_label2)]
pub head_span: Span,
}

#[derive(Diagnostic)]
#[diag(expand_macro_body_stability)]
pub(crate) struct MacroBodyStability {
Expand Down
1 change: 0 additions & 1 deletion library/core/src/array/drain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ impl<'l, 'f, T, U, const N: usize, F: FnMut(T) -> U> Drain<'l, 'f, T, N, F> {
}

/// See [`Drain::new`]; this is our fake iterator.
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
#[unstable(feature = "array_try_map", issue = "79711")]
pub(super) struct Drain<'l, 'f, T, const N: usize, F> {
// FIXME(const-hack): This is essentially a slice::IterMut<'static>, replace when possible.
Expand Down
5 changes: 5 additions & 0 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2629,6 +2629,7 @@ pub const fn overflow_checks() -> bool {
#[rustc_nounwind]
#[rustc_intrinsic]
#[miri::intrinsic_fallback_is_spec]
#[rustc_intrinsic_const_stable_indirect]
pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and make_global are needed in

let alloc: *mut u8 = const_allocate(alloc_size, alloc_align);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one really shouldn't be callable-from-stable, it is the very definition of not stable... same for const_make_global.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would strongly prefer to add allow_const_unstable to new_unsize_zst -- and we should consider if it's really safe to use these highly experimental features there.

That said, Thin is entirely unstable, so we can also add allow_const_unstable with a comment saying that this isn't actually stable -- but then we should also add that as a blocker on the tracking issue as it seems easy to miss.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would strongly prefer to add allow_const_unstable to new_unsize_zst
That does feel nicer, to guard it against any other uses. With a comment there why specifically this call needs it and is safe

// const eval overrides this function, but runtime code for now just returns null pointers.
// See <https://github.com/rust-lang/rust/issues/93935>.
Expand Down Expand Up @@ -2658,6 +2659,7 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
#[rustc_nounwind]
#[rustc_intrinsic]
#[miri::intrinsic_fallback_is_spec]
#[rustc_intrinsic_const_stable_indirect]
pub const unsafe fn const_make_global(ptr: *mut u8) -> *const u8 {
// const eval overrides this function; at runtime, it is a NOP.
ptr
Expand Down Expand Up @@ -2823,6 +2825,7 @@ pub const fn offset_of<T: PointeeSized>(variant: u32, field: u32) -> usize;
#[rustc_nounwind]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_intrinsic]
#[rustc_intrinsic_const_stable_indirect]
pub const fn variant_count<T>() -> usize;
Copy link
Member

@RalfJung RalfJung Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually stable either, I think? std::mem::variant_count is still unstable.


/// The size of the referenced value in bytes.
Expand Down Expand Up @@ -2862,6 +2865,7 @@ pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
#[rustc_nounwind]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_intrinsic]
#[rustc_intrinsic_const_stable_indirect]
pub const fn type_name<T: ?Sized>() -> &'static str;
Copy link
Member

@RalfJung RalfJung Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't const-stable, it can only be invoked via a regular function.


/// Gets an identifier which is globally unique to the specified type. This
Expand All @@ -2877,6 +2881,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
#[rustc_nounwind]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_intrinsic]
#[rustc_intrinsic_const_stable_indirect]
pub const fn type_id<T: ?Sized + 'static>() -> crate::any::TypeId;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And neither is this const-stable.


/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/attributes/const-stability-on-macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
#![stable(feature = "rust1", since = "1.0.0")]

#[rustc_const_stable(feature = "foo", since = "3.3.3")]
//~^ ERROR macros cannot have const stability attributes
//~^ ERROR attribute cannot be used on macro defs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea again am not entirely sure why removing this error from const stability is part of this PR.

macro_rules! foo {
() => {};
}

#[rustc_const_unstable(feature = "bar", issue="none")]
//~^ ERROR macros cannot have const stability attributes
#[rustc_const_unstable(feature = "bar", issue = "none")]
//~^ ERROR attribute cannot be used on macro defs
macro_rules! bar {
() => {};
}
Expand Down
20 changes: 9 additions & 11 deletions tests/ui/attributes/const-stability-on-macro.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
error: macros cannot have const stability attributes
error: `#[rustc_const_stable]` attribute cannot be used on macro defs
--> $DIR/const-stability-on-macro.rs:4:1
|
LL | #[rustc_const_stable(feature = "foo", since = "3.3.3")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
LL |
LL | macro_rules! foo {
| ---------------- const stability attribute affects this macro
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_const_stable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements

error: macros cannot have const stability attributes
error: `#[rustc_const_unstable]` attribute cannot be used on macro defs
--> $DIR/const-stability-on-macro.rs:10:1
|
LL | #[rustc_const_unstable(feature = "bar", issue="none")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
LL |
LL | macro_rules! bar {
| ---------------- const stability attribute affects this macro
LL | #[rustc_const_unstable(feature = "bar", issue = "none")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_const_unstable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements

error: aborting due to 2 previous errors

5 changes: 4 additions & 1 deletion tests/ui/consts/min_const_fn/const-fn-lang-feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ const fn my_fun2() {
}

fn main() {
const { my_fun2() };
#[rustc_const_unstable(feature = "abi_unadjusted", issue = "42")]
Copy link
Contributor

@jdonszelmann jdonszelmann Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test seems more what I expect the the goal of the PR to be. Maybe split the macro parts out and separately motivate it? Unless I'm missing how it's actually related

const {
my_fun2()
};
}
Loading