@@ -5,7 +5,7 @@ use rustc_ast::*;
55use rustc_errors:: ErrorGuaranteed ;
66use rustc_hir:: def:: { DefKind , Res } ;
77use 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 } ;
99use rustc_index:: { IndexSlice , IndexVec } ;
1010use rustc_middle:: ty:: { ResolverAstLowering , TyCtxt } ;
1111use rustc_span:: edit_distance:: find_best_match_for_name;
@@ -14,7 +14,7 @@ use smallvec::{SmallVec, smallvec};
1414use thin_vec:: ThinVec ;
1515use tracing:: instrument;
1616
17- use crate :: errors:: DistributedSliceWithInitializer ;
17+ use crate :: errors:: { DistributedSliceElementsWrongExpr , DistributedSliceWithInitializer } ;
1818
1919use 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 {
0 commit comments