Skip to content

Commit 7958dfe

Browse files
committed
Require const blocks to only use const stable things
1 parent 3b550fe commit 7958dfe

File tree

17 files changed

+218
-25
lines changed

17 files changed

+218
-25
lines changed

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
197197
}
198198
}
199199
InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const {
200-
anon_const: self.lower_const_block(anon_const),
200+
anon_const: self.lower_const_block(anon_const, &[]),
201201
},
202202
InlineAsmOperand::Sym { sym } => {
203203
let static_def_id = self

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
106106

107107
let kind = match &e.kind {
108108
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
109-
ExprKind::ConstBlock(c) => hir::ExprKind::ConstBlock(self.lower_const_block(c)),
109+
ExprKind::ConstBlock(c) => {
110+
hir::ExprKind::ConstBlock(self.lower_const_block(c, attrs))
111+
}
110112
ExprKind::Repeat(expr, count) => {
111113
let expr = self.lower_expr(expr);
112114
let count = self.lower_array_length_to_const_arg(count);
@@ -391,12 +393,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
391393
})
392394
}
393395

394-
pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock {
396+
pub(crate) fn lower_const_block(
397+
&mut self,
398+
c: &AnonConst,
399+
attrs: &'hir [hir::Attribute],
400+
) -> hir::ConstBlock {
395401
self.with_new_scopes(c.value.span, |this| {
396402
let def_id = this.local_def_id(c.id);
403+
let hir_id = this.lower_node_id(c.id);
404+
if !attrs.is_empty() {
405+
this.attrs.insert(hir_id.local_id, attrs);
406+
}
397407
hir::ConstBlock {
398408
def_id,
399-
hir_id: this.lower_node_id(c.id),
409+
hir_id,
400410
body: this.lower_const_body(c.value.span, Some(&c.value)),
401411
}
402412
})

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
399399
ExprKind::Lit(lit) => {
400400
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: false }
401401
}
402-
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)),
402+
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c, &[])),
403403
ExprKind::IncludedBytes(byte_sym) => hir::PatExprKind::Lit {
404404
lit: respan(span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)),
405405
negated: false,

compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
6363
Allow(Target::Method(MethodKind::Inherent)),
6464
Allow(Target::Method(MethodKind::Trait { body: true })),
6565
Allow(Target::Method(MethodKind::TraitImpl)),
66+
Allow(Target::Expression), // FIXME: should only allow inline consts
6667
]);
6768
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
6869

compiler/rustc_attr_parsing/src/attributes/stability.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ impl<S: Stage> AttributeParser<S> for ConstStabilityParser {
255255
Allow(Target::AssocConst),
256256
Allow(Target::Trait),
257257
Allow(Target::Static),
258+
Allow(Target::Expression), // FIXME: we really only want to allow inline consts
258259
Allow(Target::Crate),
259260
Allow(Target::MacroDef), // FIXME(oli-obk): remove this and eliminate the manual check for it
260261
]);

compiler/rustc_const_eval/src/check_consts/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
5454
pub fn enforce_recursive_const_stability(&self) -> bool {
5555
// We can skip this if neither `staged_api` nor `-Zforce-unstable-if-unmarked` are enabled,
5656
// since in such crates `lookup_const_stability` will always be `None`.
57-
self.const_kind == Some(hir::ConstContext::ConstFn)
58-
&& (self.tcx.features().staged_api()
59-
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
57+
matches!(
58+
self.const_kind,
59+
Some(hir::ConstContext::ConstFn | hir::ConstContext::Const { inline: true })
60+
) && (self.tcx.features().staged_api()
61+
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
6062
&& is_fn_or_trait_safe_to_expose_on_stable(self.tcx, self.def_id().to_def_id())
6163
}
6264

compiler/rustc_passes/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,11 @@ passes_unstable_attr_for_already_stable_feature =
576576
.item = the stability attribute annotates this item
577577
.help = consider removing the attribute
578578
579+
passes_unstable_inline_const_in_const =
580+
const stability of inline consts must match const stability of containing item
581+
.help = did you mean to use `rustc_allow_const_fn_unstable`?
582+
.note = stability marker of containing item defined here
583+
579584
passes_unsupported_attributes_in_where =
580585
most attributes are not supported in `where` clauses
581586
.help = only `#[cfg]` and `#[cfg_attr]` are supported

compiler/rustc_passes/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,16 @@ pub(crate) struct MissingConstErr {
10651065
pub fn_sig_span: Span,
10661066
}
10671067

1068+
#[derive(Diagnostic)]
1069+
#[diag(passes_unstable_inline_const_in_const)]
1070+
pub(crate) struct UnstableInlineConstInConst {
1071+
#[primary_span]
1072+
#[help]
1073+
pub span: Span,
1074+
#[note]
1075+
pub parent_span: Option<Span>,
1076+
}
1077+
10681078
#[derive(Diagnostic)]
10691079
#[diag(passes_const_stable_not_stable)]
10701080
pub(crate) struct ConstStableNotStable {

compiler/rustc_passes/src/stability.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,12 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
334334

335335
macro_rules! find_attr_span {
336336
($name:ident) => {{
337-
let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id));
337+
find_attr_span!($name, def_id)
338+
}};
339+
($name:ident, $id: expr) => {{
340+
let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id($id));
338341
find_attr!(attrs, AttributeKind::$name { span, .. } => *span)
339-
}}
342+
}};
340343
}
341344

342345
if stab.is_none()
@@ -398,6 +401,16 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
398401
self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
399402
}
400403

404+
if let DefKind::InlineConst = self.tcx.def_kind(def_id)
405+
&& const_stab.is_some()
406+
&& let parent = self.tcx.local_parent(def_id)
407+
&& self.tcx.lookup_const_stability(parent) != const_stab
408+
&& let Some(span) = find_attr_span!(ConstStability)
409+
{
410+
let parent_span = find_attr_span!(ConstStability, parent);
411+
self.tcx.dcx().emit_err(errors::UnstableInlineConstInConst { span, parent_span });
412+
}
413+
401414
// If this is marked const *stable*, it must also be regular-stable.
402415
if let Some(const_stab) = const_stab
403416
&& let Some(fn_sig) = fn_sig
@@ -478,6 +491,11 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
478491
intravisit::walk_item(self, i)
479492
}
480493

494+
fn visit_inline_const(&mut self, c: &'tcx rustc_hir::ConstBlock) -> Self::Result {
495+
self.check_compatible_stability(c.def_id);
496+
intravisit::walk_inline_const(self, c)
497+
}
498+
481499
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
482500
self.check_compatible_stability(ti.owner_id.def_id);
483501
self.check_missing_stability(ti.owner_id.def_id);
@@ -601,7 +619,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
601619
let attrs = self.tcx.hir_attrs(item.hir_id());
602620
let stab = find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span));
603621

604-
// FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
605622
let const_stab = find_attr!(attrs, AttributeKind::ConstStability{stability, ..} => *stability);
606623

607624
let unstable_feature_stab =

library/alloc/src/boxed/thin.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,12 @@ impl<H> WithHeader<H> {
321321
// of the header, past the padding, so the assigned type makes sense.
322322
// It also ensures that the address at the end of the header is sufficiently
323323
// aligned for T.
324-
let alloc: &<Dyn as Pointee>::Metadata = const {
324+
// We generate the vtable in a const block instead of having the compiler
325+
// generate it for us. The basics to allocate new memory during ctfe are
326+
// unstable, but we can always change the intrinsic logic to support the
327+
// needs of new_unsize_zst in the future.
328+
let alloc: &<Dyn as Pointee>::Metadata = #[rustc_allow_const_fn_unstable(const_heap)]
329+
const {
325330
// FIXME: just call `WithHeader::alloc_layout` with size reset to 0.
326331
// Currently that's blocked on `Layout::extend` not being `const fn`.
327332

0 commit comments

Comments
 (0)