Skip to content

Commit e7a5445

Browse files
committed
distributed_slice_elements (multiple) plus tests
1 parent 0314c6f commit e7a5445

File tree

30 files changed

+509
-73
lines changed

30 files changed

+509
-73
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3624,6 +3624,10 @@ pub enum DistributedSlice {
36243624
/// This const (we never do this to statics) represents an addition to a global registry
36253625
/// declared somewhere else.
36263626
Addition { declaration: Path, id: NodeId },
3627+
/// This const (we never do this to statics) represents an addition of an array
3628+
/// to a global registry declared somewhere else. All elements are added, though not necessarily
3629+
/// in the same order as in the original slice.
3630+
AdditionMany { declaration: Path, id: NodeId },
36273631
/// Applied to an invalid item, error guaranteed to have be emitted
36283632
Err(ErrorGuaranteed),
36293633
}

compiler/rustc_ast/src/visit.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,10 @@ macro_rules! common_visitor_and_walkers {
467467
try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?));
468468
try_visit!(visit_id(vis, id));
469469
}
470+
DistributedSlice::AdditionMany { declaration, id } => {
471+
try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?));
472+
try_visit!(visit_id(vis, id));
473+
}
470474
}
471475
walk_define_opaques(vis, define_opaque)
472476
}
@@ -645,6 +649,10 @@ macro_rules! common_visitor_and_walkers {
645649
try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?));
646650
try_visit!(visit_id(vis, id));
647651
}
652+
DistributedSlice::AdditionMany { declaration, id } => {
653+
try_visit!(vis.visit_path(declaration$(${ignore($lt)}, *id)?));
654+
try_visit!(visit_id(vis, id));
655+
}
648656
}
649657

650658

compiler/rustc_ast_lowering/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ ast_lowering_coroutine_too_many_parameters =
5656
ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs
5757
.label = default fields are only supported on structs
5858
59+
ast_lowering_distributed_slice_elements_wrong_expr =
60+
`distributed_slice_elements!()` only accepts a path or array literal
61+
.note = arbitrary expressions are not supported
5962
ast_lowering_distributed_slice_with_initializer =
6063
distributed slice elements are added with `distributed_slice_element!(...)`
6164
ast_lowering_does_not_support_modifiers =

compiler/rustc_ast_lowering/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,3 +482,11 @@ pub(crate) struct DistributedSliceWithInitializer {
482482
#[primary_span]
483483
pub span: Span,
484484
}
485+
486+
#[derive(Diagnostic)]
487+
#[diag(ast_lowering_distributed_slice_elements_wrong_expr)]
488+
#[note]
489+
pub(crate) struct DistributedSliceElementsWrongExpr {
490+
#[primary_span]
491+
pub span: Span,
492+
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use rustc_errors::ErrorGuaranteed;
66
use rustc_hir::def::{DefKind, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
88
use rustc_hir::{
9-
self as hir, DistributedSlice, HirId, InvalidDistributedSliceDeclaration, LifetimeSource,
10-
PredicateOrigin,
9+
self as hir, DistributedSlice, DistributedSliceAdditionManyKind, HirId,
10+
InvalidDistributedSliceDeclaration, LifetimeSource, PredicateOrigin,
1111
};
1212
use rustc_index::{IndexSlice, IndexVec};
1313
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -25,7 +25,7 @@ use super::{
2525
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
2626
ResolverAstLoweringExt,
2727
};
28-
use crate::errors::DistributedSliceWithInitializer;
28+
use crate::errors::{DistributedSliceElementsWrongExpr, DistributedSliceWithInitializer};
2929

3030
pub(super) struct ItemLowerer<'a, 'hir> {
3131
pub(super) tcx: TyCtxt<'hir>,
@@ -155,6 +155,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
155155
fn lower_distributed_slice(
156156
&mut self,
157157
distributed_slice: &ast::DistributedSlice,
158+
expr: Option<&Expr>,
158159
) -> DistributedSlice {
159160
match distributed_slice {
160161
ast::DistributedSlice::None => DistributedSlice::None,
@@ -179,6 +180,58 @@ impl<'hir> LoweringContext<'_, 'hir> {
179180

180181
DistributedSlice::Addition(local)
181182
}
183+
ast::DistributedSlice::AdditionMany { declaration, id } => {
184+
let Some(res) = self.resolver.get_partial_res(*id) else {
185+
self.dcx().span_delayed_bug(declaration.span, "should have errored in resolve");
186+
return DistributedSlice::None;
187+
};
188+
189+
let Some(did) = res.expect_full_res().opt_def_id() else {
190+
self.dcx().span_delayed_bug(declaration.span, "should have errored in resolve");
191+
return DistributedSlice::None;
192+
};
193+
194+
let Some(local) = did.as_local() else {
195+
panic!("adding to slice outside local crate");
196+
};
197+
198+
let initializer = expr
199+
.expect("generated by `distributed_slice_elements!` and always has an expr");
200+
201+
DistributedSlice::AdditionMany(
202+
local,
203+
match &initializer.kind {
204+
ExprKind::Array(elems) => {
205+
DistributedSliceAdditionManyKind::ArrayLit { length: elems.len() }
206+
}
207+
ExprKind::Path(_, _) => {
208+
let Some(res) = self.resolver.get_partial_res(initializer.id) else {
209+
self.dcx().span_delayed_bug(
210+
declaration.span,
211+
"should have errored in resolve",
212+
);
213+
return DistributedSlice::None;
214+
};
215+
216+
let Some(did) = res.expect_full_res().opt_def_id() else {
217+
self.dcx().span_delayed_bug(
218+
declaration.span,
219+
"should have errored in resolve",
220+
);
221+
return DistributedSlice::None;
222+
};
223+
224+
DistributedSliceAdditionManyKind::Path { res: did }
225+
}
226+
_ => {
227+
let eg = self.dcx().emit_err(DistributedSliceElementsWrongExpr {
228+
span: initializer.span,
229+
});
230+
DistributedSliceAdditionManyKind::Err(eg)
231+
}
232+
},
233+
)
234+
}
182235
}
183236
}
184237

@@ -225,7 +278,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
225278
ident,
226279
ty,
227280
body_id,
228-
self.lower_distributed_slice(distributed_slice),
281+
self.lower_distributed_slice(distributed_slice, e.as_deref()),
229282
)
230283
}
231284
ItemKind::Const(box ast::ConstItem {
@@ -258,7 +311,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
258311
generics,
259312
ty,
260313
body_id,
261-
self.lower_distributed_slice(distributed_slice),
314+
self.lower_distributed_slice(distributed_slice, expr.as_deref()),
262315
)
263316
}
264317
ItemKind::Fn(box Fn {

compiler/rustc_builtin_macros/src/distributed_slice.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,45 @@ pub(crate) fn distributed_slice_element(
143143
tokens: None
144144
})]))
145145
}
146+
147+
/// ```rust
148+
/// distributed_slice_elements!(MEOWS, ["mrow"]);
149+
/// ```
150+
pub(crate) fn distributed_slice_elements(
151+
cx: &mut ExtCtxt<'_>,
152+
span: Span,
153+
tts: TokenStream,
154+
) -> MacroExpanderResult<'static> {
155+
let (path, expr) = match parse_element(cx.new_parser_from_tts(tts)) {
156+
Ok((ident, expr)) => (ident, expr),
157+
Err(mut err) => {
158+
if err.span.is_dummy() {
159+
err.span(span);
160+
}
161+
let guar = err.emit();
162+
return ExpandResult::Ready(DummyResult::any(span, guar));
163+
}
164+
};
165+
166+
ExpandResult::Ready(MacEager::items(smallvec![P(Item {
167+
attrs: ThinVec::new(),
168+
id: DUMMY_NODE_ID,
169+
span,
170+
vis: ast::Visibility { kind: ast::VisibilityKind::Inherited, span, tokens: None },
171+
kind: ItemKind::Const(Box::new(ConstItem {
172+
defaultness: Defaultness::Final,
173+
ident: Ident { name: kw::Underscore, span },
174+
generics: Generics::default(),
175+
// leave out the ty, we discover it when
176+
// when name-resolving to the registry definition
177+
ty: P(Ty { id: DUMMY_NODE_ID, kind: TyKind::Infer, span, tokens: None }),
178+
expr: Some(expr),
179+
define_opaque: None,
180+
distributed_slice: DistributedSlice::AdditionMany {
181+
declaration: path,
182+
id: DUMMY_NODE_ID
183+
}
184+
})),
185+
tokens: None
186+
})]))
187+
}

compiler/rustc_builtin_macros/src/lib.rs

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

compiler/rustc_hir/src/hir.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,12 +4271,20 @@ impl FnHeader {
42714271
}
42724272
}
42734273

4274+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
4275+
pub enum DistributedSliceAdditionManyKind {
4276+
ArrayLit { length: usize },
4277+
Path { res: DefId },
4278+
Err(ErrorGuaranteed),
4279+
}
4280+
42744281
#[derive(Debug, Clone, Copy, HashStable_Generic, Default)]
42754282
pub enum DistributedSlice {
42764283
#[default]
42774284
None,
42784285
Declaration(Span),
42794286
Addition(LocalDefId),
4287+
AdditionMany(LocalDefId, DistributedSliceAdditionManyKind),
42804288
}
42814289

42824290
#[derive(Debug, Clone, Copy, HashStable_Generic)]

compiler/rustc_hir_analysis/src/collect/distributed_slice.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
11
use rand::SeedableRng;
22
use rand::seq::SliceRandom;
3-
use rustc_hir::def_id::{DefIdMap, LocalDefId};
3+
use rustc_hir::def_id::DefIdMap;
44
use rustc_hir::{DistributedSlice, ItemKind};
5+
use rustc_middle::middle::distributed_slice::DistributedSliceAddition;
56
use rustc_middle::ty::TyCtxt;
67

78
pub(super) fn distributed_slice_elements<'tcx>(
89
tcx: TyCtxt<'tcx>,
910
_: (),
10-
) -> DefIdMap<Vec<LocalDefId>> {
11-
let mut slice_elements = DefIdMap::<Vec<LocalDefId>>::default();
11+
) -> DefIdMap<Vec<DistributedSliceAddition>> {
12+
let mut slice_elements = DefIdMap::<Vec<DistributedSliceAddition>>::default();
1213

1314
for i in tcx.hir_free_items() {
1415
let addition_def_id = i.owner_id.def_id;
1516
if let ItemKind::Const(.., DistributedSlice::Addition(declaration_def_id)) =
1617
tcx.hir_expect_item(addition_def_id).kind
1718
{
18-
slice_elements.entry(declaration_def_id.to_def_id()).or_default().push(addition_def_id);
19+
slice_elements
20+
.entry(declaration_def_id.to_def_id())
21+
.or_default()
22+
.push(DistributedSliceAddition::Single(addition_def_id));
23+
}
24+
25+
if let ItemKind::Const(.., DistributedSlice::AdditionMany(declaration_def_id, _)) =
26+
tcx.hir_expect_item(addition_def_id).kind
27+
{
28+
slice_elements
29+
.entry(declaration_def_id.to_def_id())
30+
.or_default()
31+
.push(DistributedSliceAddition::Many(addition_def_id));
1932
}
2033
}
2134

22-
let mut res = DefIdMap::<Vec<LocalDefId>>::default();
35+
let mut res = DefIdMap::<Vec<DistributedSliceAddition>>::default();
2336

2437
for (key, mut registered_values) in
2538
tcx.with_stable_hashing_context(|hcx| slice_elements.into_sorted(&hcx, true))

0 commit comments

Comments
 (0)