@@ -320,8 +320,9 @@ fn exported_symbols_provider_local(
320
320
let need_visibility = tcx. sess . target . dynamic_linking && !tcx. sess . target . only_cdylib ;
321
321
322
322
let cgus = tcx. collect_and_partition_mono_items ( ( ) ) . codegen_units ;
323
+
324
+ // Do not export symbols that cannot be instantiated by downstream crates.
323
325
let reachable_set = tcx. reachable_set ( ( ) ) ;
324
- let visibilities = tcx. effective_visibilities ( ( ) ) ;
325
326
let is_local_to_current_crate = |ty : Ty < ' _ > | {
326
327
let no_refs = ty. peel_refs ( ) ;
327
328
let root_def_id = match no_refs. kind ( ) {
@@ -342,6 +343,17 @@ fn exported_symbols_provider_local(
342
343
let is_local = !reachable_set. contains ( & root_def_id) ;
343
344
is_local
344
345
} ;
346
+
347
+ let is_instantiable_downstream = |did, type_args| {
348
+ std:: iter:: once ( tcx. type_of ( did) . skip_binder ( ) ) . chain ( type_args) . all ( |arg| {
349
+ arg. walk ( ) . all ( |ty| {
350
+ let Some ( ty) = ty. as_type ( ) else {
351
+ return true ;
352
+ } ;
353
+ !is_local_to_current_crate ( ty)
354
+ } )
355
+ } )
356
+ } ;
345
357
// The symbols created in this loop are sorted below it
346
358
#[ allow( rustc:: potential_query_instability) ]
347
359
for ( mono_item, data) in cgus. iter ( ) . flat_map ( |cgu| cgu. items ( ) . iter ( ) ) {
@@ -370,20 +382,10 @@ fn exported_symbols_provider_local(
370
382
371
383
match * mono_item {
372
384
MonoItem :: Fn ( Instance { def : InstanceKind :: Item ( def) , args } ) => {
373
- let types = args. types ( ) ;
374
385
let has_generics = args. non_erasable_generics ( ) . next ( ) . is_some ( ) ;
375
386
376
- let should_export = has_generics
377
- && Some ( tcx. type_of ( def) . skip_binder ( ) ) . into_iter ( ) . chain ( types) . all (
378
- |arg| {
379
- arg. walk ( ) . all ( |ty| {
380
- let Some ( ty) = ty. as_type ( ) else {
381
- return true ;
382
- } ;
383
- !is_local_to_current_crate ( ty)
384
- } )
385
- } ,
386
- ) ;
387
+ let should_export =
388
+ has_generics && is_instantiable_downstream ( def, args. types ( ) ) ;
387
389
388
390
if should_export {
389
391
let symbol = ExportedSymbol :: Generic ( def, args) ;
@@ -408,20 +410,9 @@ fn exported_symbols_provider_local(
408
410
rustc_middle:: ty:: Closure ( id, args) => Some ( ( * id, args) ) ,
409
411
_ => None ,
410
412
} ;
411
- if let Some ( ( did, args) ) = root_identifier {
412
- did. as_local ( ) . is_some_and ( |local_did| {
413
- visibilities. public_at_level ( local_did) . is_some ( )
414
- } ) || args. types ( ) . all ( |arg| {
415
- arg. walk ( ) . all ( |ty| {
416
- let Some ( ty) = ty. as_type ( ) else {
417
- return true ;
418
- } ;
419
- !is_local_to_current_crate ( ty)
420
- } )
421
- } )
422
- } else {
423
- true
424
- }
413
+ root_identifier. map_or ( true , |( did, args) | {
414
+ is_instantiable_downstream ( did, args. types ( ) )
415
+ } )
425
416
} ;
426
417
if should_export {
427
418
symbols. push ( (
0 commit comments