@@ -320,8 +320,9 @@ fn exported_symbols_provider_local(
320320 let need_visibility = tcx. sess . target . dynamic_linking && !tcx. sess . target . only_cdylib ;
321321
322322 let cgus = tcx. collect_and_partition_mono_items ( ( ) ) . codegen_units ;
323+
324+ // Do not export symbols that cannot be instantiated by downstream crates.
323325 let reachable_set = tcx. reachable_set ( ( ) ) ;
324- let visibilities = tcx. effective_visibilities ( ( ) ) ;
325326 let is_local_to_current_crate = |ty : Ty < ' _ > | {
326327 let no_refs = ty. peel_refs ( ) ;
327328 let root_def_id = match no_refs. kind ( ) {
@@ -342,6 +343,17 @@ fn exported_symbols_provider_local(
342343 let is_local = !reachable_set. contains ( & root_def_id) ;
343344 is_local
344345 } ;
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+ } ;
345357 // The symbols created in this loop are sorted below it
346358 #[ allow( rustc:: potential_query_instability) ]
347359 for ( mono_item, data) in cgus. iter ( ) . flat_map ( |cgu| cgu. items ( ) . iter ( ) ) {
@@ -370,20 +382,10 @@ fn exported_symbols_provider_local(
370382
371383 match * mono_item {
372384 MonoItem :: Fn ( Instance { def : InstanceKind :: Item ( def) , args } ) => {
373- let types = args. types ( ) ;
374385 let has_generics = args. non_erasable_generics ( ) . next ( ) . is_some ( ) ;
375386
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 ( ) ) ;
387389
388390 if should_export {
389391 let symbol = ExportedSymbol :: Generic ( def, args) ;
@@ -408,20 +410,9 @@ fn exported_symbols_provider_local(
408410 rustc_middle:: ty:: Closure ( id, args) => Some ( ( * id, args) ) ,
409411 _ => None ,
410412 } ;
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+ } )
425416 } ;
426417 if should_export {
427418 symbols. push ( (
0 commit comments