@@ -118,59 +118,57 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
118
118
// This is sort of subtle. Inside our codegen unit we started off
119
119
// compilation by predefining all our own `TransItem` instances. That
120
120
// is, everything we're translating ourselves is already defined. That
121
- // means that anything we're actually translating ourselves will have
122
- // hit the above branch in `get_declared_value`. As a result, we're
123
- // guaranteed here that we're declaring a symbol that won't get defined,
124
- // or in other words we're referencing a foreign value.
121
+ // means that anything we're actually translating in this codegen unit
122
+ // will have hit the above branch in `get_declared_value`. As a result,
123
+ // we're guaranteed here that we're declaring a symbol that won't get
124
+ // defined, or in other words we're referencing a value from another
125
+ // codegen unit or even another crate.
125
126
//
126
127
// So because this is a foreign value we blanket apply an external
127
128
// linkage directive because it's coming from a different object file.
128
129
// The visibility here is where it gets tricky. This symbol could be
129
130
// referencing some foreign crate or foreign library (an `extern`
130
131
// block) in which case we want to leave the default visibility. We may
131
- // also, though, have multiple codegen units.
132
- //
133
- // In the situation of multiple codegen units this function may be
134
- // referencing a function from another codegen unit. If we're
135
- // indeed referencing a symbol in another codegen unit then we're in one
136
- // of two cases:
137
- //
138
- // * This is a symbol defined in a foreign crate and we're just
139
- // monomorphizing in another codegen unit. In this case this symbols
140
- // is for sure not exported, so both codegen units will be using
141
- // hidden visibility. Hence, we apply a hidden visibility here.
142
- //
143
- // * This is a symbol defined in our local crate. If the symbol in the
144
- // other codegen unit is also not exported then like with the foreign
145
- // case we apply a hidden visibility. If the symbol is exported from
146
- // the foreign object file, however, then we leave this at the
147
- // default visibility as we'll just import it naturally.
132
+ // also, though, have multiple codegen units. It could be a
133
+ // monomorphization, in which case its expected visibility depends on
134
+ // whether we are sharing generics or not. The important thing here is
135
+ // that the visibility we apply to the declaration is the same one that
136
+ // has been applied to the definition (wherever that definition may be).
148
137
unsafe {
149
138
llvm:: LLVMRustSetLinkage ( llfn, llvm:: Linkage :: ExternalLinkage ) ;
150
139
151
140
let is_generic = instance. substs . types ( ) . next ( ) . is_some ( ) ;
152
141
153
142
if is_generic {
143
+ // This is a monomorphization. Its expected visibility depends
144
+ // on whether we are in share-generics mode.
145
+
154
146
if cx. tcx . share_generics ( ) {
155
147
// We are in share_generics mode.
156
148
157
149
if instance_def_id. is_local ( ) {
158
150
// This is a definition from the current crate. If the
159
151
// definition is unreachable for downstream crates or
160
152
// the current crate does not re-export generics, the
161
- // instance has been hidden
153
+ // definition of the instance will have been declared
154
+ // as `hidden`.
162
155
if cx. tcx . is_unreachable_local_definition ( instance_def_id) ||
163
156
!cx. tcx . local_crate_exports_generics ( ) {
164
157
llvm:: LLVMRustSetVisibility ( llfn, llvm:: Visibility :: Hidden ) ;
165
158
}
166
159
} else {
160
+ // This is a monomorphization of a generic function
161
+ // defined in an upstream crate.
167
162
if cx. tcx . upstream_monomorphizations_for ( instance_def_id)
168
163
. map ( |set| set. contains_key ( instance. substs ) )
169
164
. unwrap_or ( false ) {
170
- // This is instantiated in another crate. It cannot be hidden
165
+ // This is instantiated in another crate. It cannot
166
+ // be `hidden`.
171
167
} else {
172
168
// This is a local instantiation of an upstream definition.
173
- // If the current crate does not re-export it, it is hidden.
169
+ // If the current crate does not re-export it
170
+ // (because it is a C library or an executable), it
171
+ // will have been declared `hidden`.
174
172
if !cx. tcx . local_crate_exports_generics ( ) {
175
173
llvm:: LLVMRustSetVisibility ( llfn, llvm:: Visibility :: Hidden ) ;
176
174
}
0 commit comments