Skip to content
Draft
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
37 changes: 33 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3553,6 +3553,7 @@ impl Item {
pub fn opt_generics(&self) -> Option<&Generics> {
match &self.kind {
ItemKind::ExternCrate(..)
| ItemKind::ConstBlock(_)
| ItemKind::Use(_)
| ItemKind::Mod(..)
| ItemKind::ForeignMod(_)
Expand Down Expand Up @@ -3794,6 +3795,15 @@ impl ConstItemRhs {
}
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct ConstBlockItem {
pub body: Box<Expr>,
}

impl ConstBlockItem {
pub const IDENT: Ident = Ident { name: kw::Underscore, span: DUMMY_SP };
}

// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ItemKind {
Expand All @@ -3813,6 +3823,11 @@ pub enum ItemKind {
///
/// E.g., `const FOO: i32 = 42;`.
Const(Box<ConstItem>),
/// A module-level const block.
/// Equivalent to `const _: () = const { ... }`.
///
/// E.g., `const { assert!(true) }`.
ConstBlock(ConstBlockItem),
/// A function declaration (`fn`).
///
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
Expand Down Expand Up @@ -3889,6 +3904,8 @@ impl ItemKind {
| ItemKind::MacroDef(ident, _)
| ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),

ItemKind::ConstBlock(_) => Some(ConstBlockItem::IDENT),

ItemKind::Use(_)
| ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_)
Expand All @@ -3902,9 +3919,9 @@ impl ItemKind {
pub fn article(&self) -> &'static str {
use ItemKind::*;
match self {
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
| Delegation(..) | DelegationMac(..) => "a",
Use(..) | Static(..) | Const(..) | ConstBlock(..) | Fn(..) | Mod(..)
| GlobalAsm(..) | TyAlias(..) | Struct(..) | Union(..) | Trait(..) | TraitAlias(..)
| MacroDef(..) | Delegation(..) | DelegationMac(..) => "a",
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
}
}
Expand All @@ -3915,6 +3932,7 @@ impl ItemKind {
ItemKind::Use(..) => "`use` import",
ItemKind::Static(..) => "static item",
ItemKind::Const(..) => "constant item",
ItemKind::ConstBlock(..) => "const block",
ItemKind::Fn(..) => "function",
ItemKind::Mod(..) => "module",
ItemKind::ForeignMod(..) => "extern block",
Expand Down Expand Up @@ -3944,7 +3962,18 @@ impl ItemKind {
| Self::Trait(box Trait { generics, .. })
| Self::TraitAlias(box TraitAlias { generics, .. })
| Self::Impl(Impl { generics, .. }) => Some(generics),
_ => None,

Self::ExternCrate(..)
| Self::Use(..)
| Self::Static(..)
| Self::ConstBlock(..)
| Self::Mod(..)
| Self::ForeignMod(..)
| Self::GlobalAsm(..)
| Self::MacCall(..)
| Self::MacroDef(..)
| Self::Delegation(..)
| Self::DelegationMac(..) => None,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ macro_rules! common_visitor_and_walkers {
ByRef,
Closure,
Const,
ConstBlockItem,
ConstItem,
ConstItemRhs,
Defaultness,
Expand Down Expand Up @@ -819,6 +820,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!($($mut)? vis, use_tree),
ItemKind::Static(item) =>
visit_visitable!($($mut)? vis, item),
ItemKind::ConstBlock(item) =>
visit_visitable!($($mut)? vis, item),
ItemKind::Const(item) =>
visit_visitable!($($mut)? vis, item),
ItemKind::Mod(safety, ident, mod_kind) =>
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_define_opaque(hir_id, define_opaque);
hir::ItemKind::Static(*m, ident, ty, body_id)
}
ItemKind::Const(box ast::ConstItem {
ident, generics, ty, rhs, define_opaque, ..
ItemKind::Const(box ConstItem {
defaultness: _,
ident,
generics,
ty,
rhs,
define_opaque,
}) => {
let ident = self.lower_ident(*ident);
let (generics, (ty, rhs)) = self.lower_generics(
Expand All @@ -201,6 +206,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_define_opaque(hir_id, &define_opaque);
hir::ItemKind::Const(ident, generics, ty, rhs)
}
ItemKind::ConstBlock(ConstBlockItem { body }) => hir::ItemKind::Const(
self.lower_ident(ConstBlockItem::IDENT),
hir::Generics::empty(),
self.arena.alloc(self.ty_tup(DUMMY_SP, &[])),
hir::ConstItemRhs::Body({
let body = self.lower_expr_mut(body);
self.record_body(&[], body)
}),
),
ItemKind::Fn(box Fn {
sig: FnSig { decl, header, span: fn_sig_span },
ident,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(super_let, "`super let` is experimental");
gate_all!(frontmatter, "frontmatters are experimental");
gate_all!(coroutines, "coroutine syntax is experimental");
gate_all!(const_block_items, "const block items are experimental");

if !visitor.features.never_patterns() {
if let Some(spans) = spans.get(&sym::never_patterns) {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ impl<'a> State<'a> {
define_opaque.as_deref(),
);
}
ast::ItemKind::ConstBlock(ast::ConstBlockItem { body }) => {
self.print_expr(body, FixupContext::default())
}
ast::ItemKind::Const(box ast::ConstItem {
defaultness,
ident,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_builtin_macros/src/cfg_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_expand::config::StripUnconfigured;
use rustc_expand::configure;
use rustc_feature::Features;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser};
use rustc_session::Session;
use rustc_span::{Span, sym};
use smallvec::SmallVec;
Expand Down Expand Up @@ -113,7 +113,8 @@ impl CfgEval<'_> {
let res: PResult<'_, Annotatable> = try {
match annotatable {
Annotatable::Item(_) => {
let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
let item =
parser.parse_item(ForceCollect::Yes, AllowConstBlockItems::Yes)?.unwrap();
Annotatable::Item(self.flat_map_item(item).pop().unwrap())
}
Annotatable::AssocItem(_, ctxt) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_expand::base::{
};
use rustc_expand::module::DirOwnership;
use rustc_parse::lexer::StripTokens;
use rustc_parse::parser::ForceCollect;
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect};
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
use rustc_session::parse::ParseSess;
Expand Down Expand Up @@ -173,7 +173,7 @@ pub(crate) fn expand_include<'cx>(
));
let mut ret = SmallVec::new();
loop {
match p.parse_item(ForceCollect::No) {
match p.parse_item(ForceCollect::No, AllowConstBlockItems::Yes) {
Err(err) => {
err.emit();
break;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_hir::limit::Limit;
use rustc_hir::{Stability, find_attr};
use rustc_lint_defs::RegisteredTools;
use rustc_parse::MACRO_ARGUMENTS;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser};
use rustc_session::Session;
use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::parse::ParseSess;
Expand Down Expand Up @@ -1497,7 +1497,7 @@ pub(crate) fn stream_pretty_printing_compatibility_hack(
let mut parser = Parser::new(psess, stream.clone(), None);
// No need to collect tokens for this simple check.
parser
.parse_item(ForceCollect::No)
.parse_item(ForceCollect::No, AllowConstBlockItems::FIXME)
.expect("failed to reparse item")
.expect("an actual item")
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use rustc_hir::Target;
use rustc_hir::def::MacroKinds;
use rustc_hir::limit::Limit;
use rustc_parse::parser::{
AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma,
token_descr,
AllowConstBlockItems, AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser,
RecoverColon, RecoverComma, token_descr,
};
use rustc_session::Session;
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
Expand Down Expand Up @@ -1096,7 +1096,7 @@ pub fn parse_ast_fragment<'a>(
Ok(match kind {
AstFragmentKind::Items => {
let mut items = SmallVec::new();
while let Some(item) = this.parse_item(ForceCollect::No)? {
while let Some(item) = this.parse_item(ForceCollect::No, AllowConstBlockItems::Yes)? {
items.push(item);
}
AstFragment::Items(items)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl MultiItemModifier for DeriveProcMacro {
let mut items = vec![];

loop {
match parser.parse_item(ForceCollect::No) {
match parser.parse_item(ForceCollect::No, (!is_stmt).into()) {
Ok(None) => break,
Ok(Some(item)) => {
if is_stmt {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ declare_features! (
(unstable, cmse_nonsecure_entry, "1.48.0", Some(75835)),
/// Allows `async {}` expressions in const contexts.
(unstable, const_async_blocks, "1.53.0", Some(85368)),
/// Allows `const { ... }` as a shorthand for `const _: () = const { ... };` for module items.
(unstable, const_block_items, "CURRENT_RUSTC_VERSION", Some(149226)),
/// Allows `const || {}` closures in const contexts.
(incomplete, const_closures, "1.68.0", Some(106003)),
/// Allows using `[const] Destruct` bounds and calling drop impls in const contexts.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ impl Target {
ast::ItemKind::Use(..) => Target::Use,
ast::ItemKind::Static { .. } => Target::Static,
ast::ItemKind::Const(..) => Target::Const,
ast::ItemKind::ConstBlock(..) => Target::Const,
ast::ItemKind::Fn { .. } => Target::Fn,
ast::ItemKind::Mod(..) => Target::Mod,
ast::ItemKind::ForeignMod { .. } => Target::ForeignMod,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use thin_vec::ThinVec;
use tracing::debug;

use super::{
AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle, Trailing, UsePreAttrPos,
AllowConstBlockItems, AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle,
Trailing, UsePreAttrPos,
};
use crate::parser::FnContext;
use crate::{errors, exp, fluent_generated as fluent};
Expand Down Expand Up @@ -203,6 +204,7 @@ impl<'a> Parser<'a> {
false,
FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true },
ForceCollect::No,
AllowConstBlockItems::FIXME,
) {
Ok(Some(item)) => {
// FIXME(#100717)
Expand Down
Loading
Loading