Skip to content

Commit 29f698f

Browse files
committed
add register macro
1 parent 2446c32 commit 29f698f

File tree

13 files changed

+131
-25
lines changed

13 files changed

+131
-25
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3623,7 +3623,7 @@ pub enum DistributedSlice {
36233623
Declaration(Span),
36243624
/// This const (we never do this to statics) represents an addition to a global registry
36253625
/// declared somewhere else.
3626-
Addition { declaration: Path },
3626+
Addition { declaration: Path, id: NodeId },
36273627
}
36283628

36293629
#[derive(Clone, Encodable, Decodable, Debug)]

compiler/rustc_ast/src/visit.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,16 @@ macro_rules! common_visitor_and_walkers {
451451
mutability: _,
452452
expr,
453453
define_opaque,
454-
distributed_slice: _,
454+
distributed_slice,
455455
}) => {
456456
try_visit!(vis.visit_ident(ident));
457457
try_visit!(vis.visit_ty(ty));
458458
visit_opt!(vis, visit_expr, expr);
459+
match distributed_slice {
460+
DistributedSlice::None => {}
461+
DistributedSlice::Declaration(span) => try_visit!(visit_span(vis, span)),
462+
DistributedSlice::Addition { declaration, id } => try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?)),
463+
}
459464
walk_define_opaques(vis, define_opaque)
460465
}
461466
ItemKind::Const(item) => {
@@ -615,12 +620,20 @@ macro_rules! common_visitor_and_walkers {
615620
}
616621

617622
fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
618-
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque, distributed_slice: _ } = item;
623+
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque, distributed_slice } = item;
619624
try_visit!(visit_defaultness(vis, defaultness));
620625
try_visit!(vis.visit_ident(ident));
621626
try_visit!(vis.visit_generics(generics));
622627
try_visit!(vis.visit_ty(ty));
623628
visit_opt!(vis, visit_expr, expr);
629+
630+
match distributed_slice {
631+
DistributedSlice::None => {}
632+
DistributedSlice::Declaration(span) => try_visit!(visit_span(vis, span)),
633+
DistributedSlice::Addition { declaration, id } => try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?)),
634+
}
635+
636+
624637
walk_define_opaques(vis, define_opaque)
625638
}
626639

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use super::{
2222
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
2323
ResolverAstLoweringExt,
2424
};
25+
use crate::AllowReturnTypeNotation;
2526

2627
pub(super) struct ItemLowerer<'a, 'hir> {
2728
pub(super) tcx: TyCtxt<'hir>,
@@ -157,9 +158,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
157158
ast::DistributedSlice::Declaration(span) => {
158159
DistributedSlice::Declaration(self.lower_span(*span))
159160
}
160-
ast::DistributedSlice::Addition { declaration } => {
161-
// DistributedSlice::Addition(self.lower_qpath(id, qself, p, param_mode, allow_return_type_notation, itctx, modifiers))
162-
todo!()
161+
ast::DistributedSlice::Addition { declaration, id } => {
162+
DistributedSlice::Addition(self.lower_qpath(
163+
*id,
164+
&None,
165+
declaration,
166+
ParamMode::Optional,
167+
AllowReturnTypeNotation::No,
168+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
169+
None,
170+
))
163171
}
164172
}
165173
}

compiler/rustc_builtin_macros/src/distributed_slice.rs

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
use rustc_ast::{DistributedSlice, ItemKind, ast};
2-
use rustc_expand::base::{Annotatable, ExtCtxt};
3-
use rustc_span::Span;
1+
use rustc_ast::ptr::P;
2+
use rustc_ast::tokenstream::TokenStream;
3+
use rustc_ast::{
4+
ConstItem, DUMMY_NODE_ID, Defaultness, DistributedSlice, Expr, Generics, Item, ItemKind, Path,
5+
Ty, TyKind, ast,
6+
};
7+
use rustc_errors::PResult;
8+
use rustc_expand::base::{
9+
Annotatable, DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult,
10+
};
11+
use rustc_parse::exp;
12+
use rustc_parse::parser::{Parser, PathStyle};
13+
use rustc_span::{Ident, Span, kw};
14+
use smallvec::smallvec;
15+
use thin_vec::ThinVec;
416

17+
/// ```rust
18+
/// #[distributed_slice(crate)]
19+
/// const MEOWS: [&str; _];
20+
/// ```
521
pub(crate) fn distributed_slice(
622
_ecx: &mut ExtCtxt<'_>,
723
span: Span,
@@ -12,7 +28,7 @@ pub(crate) fn distributed_slice(
1228
// FIXME(gr): check item
1329

1430
let Annotatable::Item(item) = &mut orig_item else {
15-
panic!("expected `#[distributed_slice]` on an item")
31+
panic!("expected `#[distributed_slice(crate)]` on an item")
1632
};
1733

1834
match &mut item.kind {
@@ -23,9 +39,58 @@ pub(crate) fn distributed_slice(
2339
const_item.distributed_slice = DistributedSlice::Declaration(span);
2440
}
2541
other => {
26-
panic!("expected `#[distributed_slice]` on a const or static item, not {other:?}");
42+
panic!(
43+
"expected `#[distributed_slice(crate)]` on a const or static item, not {other:?}"
44+
);
2745
}
2846
}
2947

3048
vec![orig_item]
3149
}
50+
51+
fn parse_element(mut p: Parser<'_>) -> PResult<'_, (Path, P<Expr>)> {
52+
let ident = p.parse_path(PathStyle::Expr)?;
53+
p.expect(exp![Comma])?;
54+
let expr = p.parse_expr()?;
55+
56+
// optional trailing comma
57+
let _ = p.eat(exp![Comma]);
58+
59+
Ok((ident, expr))
60+
}
61+
62+
/// ```rust
63+
/// distributed_slice_element!(MEOWS, "mrow");
64+
/// ```
65+
pub(crate) fn distributed_slice_element(
66+
cx: &mut ExtCtxt<'_>,
67+
span: Span,
68+
tts: TokenStream,
69+
) -> MacroExpanderResult<'static> {
70+
let (path, expr) = match parse_element(cx.new_parser_from_tts(tts)) {
71+
Ok((ident, expr)) => (ident, expr),
72+
Err(err) => {
73+
let guar = err.emit();
74+
return ExpandResult::Ready(DummyResult::any(span, guar));
75+
}
76+
};
77+
78+
ExpandResult::Ready(MacEager::items(smallvec![P(Item {
79+
attrs: ThinVec::new(),
80+
id: DUMMY_NODE_ID,
81+
span,
82+
vis: ast::Visibility { kind: ast::VisibilityKind::Inherited, span, tokens: None },
83+
kind: ItemKind::Const(Box::new(ConstItem {
84+
defaultness: Defaultness::Final,
85+
ident: Ident { name: kw::Underscore, span },
86+
generics: Generics::default(),
87+
// leave out the ty, we discover it when
88+
// when name-resolving to the registry definition
89+
ty: P(Ty { id: DUMMY_NODE_ID, kind: TyKind::Infer, span, tokens: None }),
90+
expr: Some(expr),
91+
define_opaque: None,
92+
distributed_slice: DistributedSlice::Addition { declaration: path, id: DUMMY_NODE_ID }
93+
})),
94+
tokens: None
95+
})]))
96+
}

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
8888
concat_idents: concat_idents::expand_concat_idents,
8989
const_format_args: format::expand_format_args,
9090
core_panic: edition_panic::expand_panic,
91+
distributed_slice_element: distributed_slice::distributed_slice_element,
9192
env: env::expand_env,
9293
file: source_util::expand_file,
9394
format_args: format::expand_format_args,

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use diagnostics::AttemptLocalParseRecovery;
2020
pub(crate) use expr::ForbiddenLetReason;
2121
pub(crate) use item::FnParseMode;
2222
pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
23-
use path::PathStyle;
23+
pub use path::PathStyle;
2424
use rustc_ast::ptr::P;
2525
use rustc_ast::token::{
2626
self, IdentIsRaw, InvisibleOrigin, MetaVarKind, NtExprKind, NtPatKind, Token, TokenKind,

compiler/rustc_parse/src/parser/path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
2525

2626
/// Specifies how to parse a path.
2727
#[derive(Copy, Clone, PartialEq)]
28-
pub(super) enum PathStyle {
28+
pub enum PathStyle {
2929
/// In some contexts, notably in expressions, paths with generic arguments are ambiguous
3030
/// with something else. For example, in expressions `segment < ....` can be interpreted
3131
/// as a comparison and `segment ( ....` can be interpreted as a function call.
@@ -149,7 +149,7 @@ impl<'a> Parser<'a> {
149149
true
150150
}
151151

152-
pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
152+
pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
153153
self.parse_path_inner(style, None)
154154
}
155155

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,7 @@ symbols! {
834834
disjoint_bitor,
835835
dispatch_from_dyn,
836836
distributed_slice,
837+
distributed_slice_element,
837838
div,
838839
div_assign,
839840
diverging_block_default,

library/core/src/macros/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,4 +1814,14 @@ pub(crate) mod builtin {
18141814
pub macro distributed_slice($item:item) {
18151815
/* compiler built-in */
18161816
}
1817+
1818+
/// Create a global registry.
1819+
///
1820+
// FIXME(gr): docs
1821+
#[unstable(feature = "crate_local_distributed_slice", issue = "125119")]
1822+
#[rustc_builtin_macro]
1823+
#[cfg(not(bootstrap))]
1824+
pub macro distributed_slice_element($path:path, $expr:expr) {
1825+
/* compiler built-in */
1826+
}
18171827
}

library/core/src/prelude/v1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub use crate::macros::builtin::{
8383

8484
#[unstable(feature = "crate_local_distributed_slice", issue = "125119")]
8585
#[cfg(not(bootstrap))]
86-
pub use crate::macros::builtin::distributed_slice;
86+
pub use crate::macros::builtin::{distributed_slice, distributed_slice_element};
8787

8888
#[unstable(feature = "derive_const", issue = "none")]
8989
pub use crate::macros::builtin::derive_const;

library/std/src/prelude/v1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub use core::prelude::v1::{
7070

7171
#[unstable(feature = "crate_local_distributed_slice", issue = "125119")]
7272
#[cfg(not(bootstrap))]
73-
pub use core::prelude::v1::distributed_slice;
73+
pub use core::prelude::v1::{distributed_slice, distributed_slice_element};
7474

7575
#[unstable(feature = "derive_const", issue = "none")]
7676
pub use core::prelude::v1::derive_const;

tests/ui/crate_local_distributed_slice/create_slice.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44
#[distributed_slice(crate)]
55
const MEOWS: [&str; _];
66

7-
fn main() {}
7+
distributed_slice_element!(MEOWS, "mrow");
8+
9+
fn main() {
10+
println!("{MEOWS:?}");
11+
}
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
error: free constant item without body
2-
--> $DIR/create_slice.rs:5:1
3-
|
4-
LL | const MEOWS: [&str; _];
5-
| ^^^^^^^^^^^^^^^^^^^^^^-
6-
| |
7-
| help: provide a definition for the constant: `= <expr>;`
8-
91
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
102
--> $DIR/create_slice.rs:5:21
113
|
124
LL | const MEOWS: [&str; _];
135
| ^ not allowed in type signatures
146

7+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
8+
--> $DIR/create_slice.rs:7:1
9+
|
10+
LL | distributed_slice_element!(MEOWS, "mrow");
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed in type signatures
12+
|
13+
help: replace this with a fully-specified type
14+
|
15+
LL - distributed_slice_element!(MEOWS, "mrow");
16+
LL + &str;
17+
|
18+
1519
error: aborting due to 2 previous errors
1620

1721
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)