Skip to content

Commit ac0ac27

Browse files
committed
distributed_slice_elements (multiple) plus tests
1 parent 60694c7 commit ac0ac27

File tree

31 files changed

+477
-65
lines changed

31 files changed

+477
-65
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3611,6 +3611,10 @@ pub enum DistributedSlice {
36113611
/// This const (we never do this to statics) represents an addition to a global registry
36123612
/// declared somewhere else.
36133613
Addition { declaration: Path, id: NodeId },
3614+
/// This const (we never do this to statics) represents an addition of an array
3615+
/// to a global registry declared somewhere else. All elements are added, though not necessarily
3616+
/// in the same order as in the original slice.
3617+
AdditionMany { declaration: Path, id: NodeId },
36143618
/// Applied to an invalid item, error guaranteed to have be emitted
36153619
Err(ErrorGuaranteed),
36163620
}

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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,7 @@ ast_lowering_yield_in_closure =
193193
194194
ast_lowering_distributed_slice_with_initializer =
195195
distributed slice elements are added with `distributed_slice_element!(...)`
196+
197+
ast_lowering_distributed_slice_elements_wrong_expr =
198+
`distributed_slice_elements!()` only accepts a path or array literal
199+
.note = arbitrary expressions are not supported

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: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::*;
55
use rustc_errors::ErrorGuaranteed;
66
use rustc_hir::def::{DefKind, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
8-
use rustc_hir::{self as hir, DistributedSlice, HirId, InvalidDistributedSliceDeclaration, LifetimeSource, PredicateOrigin};
8+
use rustc_hir::{self as hir, DistributedSlice, DistributedSliceAdditionManyKind, HirId, InvalidDistributedSliceDeclaration, LifetimeSource, PredicateOrigin};
99
use rustc_index::{IndexSlice, IndexVec};
1010
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
1111
use rustc_span::edit_distance::find_best_match_for_name;
@@ -14,7 +14,7 @@ use smallvec::{SmallVec, smallvec};
1414
use thin_vec::ThinVec;
1515
use tracing::instrument;
1616

17-
use crate::errors::DistributedSliceWithInitializer;
17+
use crate::errors::{DistributedSliceElementsWrongExpr, DistributedSliceWithInitializer};
1818

1919
use super::errors::{
2020
InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound, TupleStructWithDefault,
@@ -153,6 +153,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
153153
fn lower_distributed_slice(
154154
&mut self,
155155
distributed_slice: &ast::DistributedSlice,
156+
expr: Option<&Expr>,
156157
) -> DistributedSlice {
157158
match distributed_slice {
158159
ast::DistributedSlice::None => DistributedSlice::None,
@@ -177,6 +178,49 @@ impl<'hir> LoweringContext<'_, 'hir> {
177178

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

@@ -223,7 +267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
223267
ty,
224268
*m,
225269
body_id,
226-
self.lower_distributed_slice(distributed_slice),
270+
self.lower_distributed_slice(distributed_slice, e.as_deref()),
227271
)
228272
}
229273
ItemKind::Const(box ast::ConstItem {
@@ -256,7 +300,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
256300
ty,
257301
generics,
258302
body_id,
259-
self.lower_distributed_slice(distributed_slice),
303+
self.lower_distributed_slice(distributed_slice, expr.as_deref()),
260304
)
261305
}
262306
ItemKind::Fn(box Fn {

compiler/rustc_builtin_macros/src/distributed_slice.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,42 @@ pub(crate) fn distributed_slice_element(
126126
tokens: None
127127
})]))
128128
}
129+
130+
/// ```rust
131+
/// distributed_slice_elements!(MEOWS, ["mrow"]);
132+
/// ```
133+
pub(crate) fn distributed_slice_elements(
134+
cx: &mut ExtCtxt<'_>,
135+
span: Span,
136+
tts: TokenStream,
137+
) -> MacroExpanderResult<'static> {
138+
let (path, expr) = match parse_element(cx.new_parser_from_tts(tts)) {
139+
Ok((ident, expr)) => (ident, expr),
140+
Err(mut err) => {
141+
if err.span.is_dummy() {
142+
err.span(span);
143+
}
144+
let guar = err.emit();
145+
return ExpandResult::Ready(DummyResult::any(span, guar));
146+
}
147+
};
148+
149+
ExpandResult::Ready(MacEager::items(smallvec![P(Item {
150+
attrs: ThinVec::new(),
151+
id: DUMMY_NODE_ID,
152+
span,
153+
vis: ast::Visibility { kind: ast::VisibilityKind::Inherited, span, tokens: None },
154+
kind: ItemKind::Const(Box::new(ConstItem {
155+
defaultness: Defaultness::Final,
156+
ident: Ident { name: kw::Underscore, span },
157+
generics: Generics::default(),
158+
// leave out the ty, we discover it when
159+
// when name-resolving to the registry definition
160+
ty: P(Ty { id: DUMMY_NODE_ID, kind: TyKind::Infer, span, tokens: None }),
161+
expr: Some(expr),
162+
define_opaque: None,
163+
distributed_slice: DistributedSlice::AdditionMany { declaration: path, id: DUMMY_NODE_ID }
164+
})),
165+
tokens: None
166+
})]))
167+
}

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
9191
const_format_args: format::expand_format_args,
9292
core_panic: edition_panic::expand_panic,
9393
distributed_slice_element: distributed_slice::distributed_slice_element,
94+
distributed_slice_elements: distributed_slice::distributed_slice_elements,
9495
env: env::expand_env,
9596
file: source_util::expand_file,
9697
format_args: format::expand_format_args,

compiler/rustc_hir/src/hir.rs

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

4274+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
4275+
pub enum DistributedSliceAdditionManyKind {
4276+
ArrayLit {
4277+
length: usize,
4278+
},
4279+
Path {
4280+
res: DefId,
4281+
},
4282+
Err(ErrorGuaranteed),
4283+
}
4284+
42744285
#[derive(Debug, Clone, Copy, HashStable_Generic, Default)]
42754286
pub enum DistributedSlice {
42764287
#[default]
42774288
None,
42784289
Declaration(Span),
42794290
Addition(LocalDefId),
4291+
AdditionMany(LocalDefId, DistributedSliceAdditionManyKind),
42804292
}
42814293

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

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,3 +631,4 @@ hir_analysis_distributed_slice_non_array =
631631
expected this type to be an array
632632
.note = a distributed slice must have an array type with an inferred length
633633
.suggestion = change the type to an array
634+

compiler/rustc_hir_analysis/src/collect/distributed_slice.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
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.entry(declaration_def_id.to_def_id()).or_default().push(DistributedSliceAddition::Single(addition_def_id));
20+
}
21+
22+
if let ItemKind::Const(.., DistributedSlice::AdditionMany(declaration_def_id, _)) =
23+
tcx.hir_expect_item(addition_def_id).kind
24+
{
25+
slice_elements.entry(declaration_def_id.to_def_id()).or_default().push(DistributedSliceAddition::Many(addition_def_id));
1926
}
2027
}
2128

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

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

0 commit comments

Comments
 (0)