@@ -31,7 +31,7 @@ use rustc::traits;
31
31
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
32
32
use rustc:: ty:: subst:: { Subst , Substs } ;
33
33
use syntax:: ast;
34
- use syntax:: attr;
34
+ use syntax:: attr:: { self , InlineAttr } ;
35
35
use syntax_pos:: Span ;
36
36
use syntax_pos:: symbol:: Symbol ;
37
37
use type_of;
@@ -175,16 +175,32 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug {
175
175
176
176
match * self . as_trans_item ( ) {
177
177
TransItem :: Fn ( ref instance) => {
178
- if self . explicit_linkage ( tcx) . is_none ( ) &&
179
- common:: requests_inline ( tcx, instance)
178
+ // If this function isn't inlined or otherwise has explicit
179
+ // linkage, then we'll be creating a globally shared version.
180
+ if self . explicit_linkage ( tcx) . is_some ( ) ||
181
+ !common:: requests_inline ( tcx, instance)
180
182
{
181
- if inline_in_all_cgus {
182
- InstantiationMode :: LocalCopy
183
- } else {
183
+ return InstantiationMode :: GloballyShared { may_conflict : false }
184
+ }
185
+
186
+ // At this point we don't have explicit linkage and we're an
187
+ // inlined function. If we're inlining into all CGUs then we'll
188
+ // be creating a local copy per CGU
189
+ if inline_in_all_cgus {
190
+ return InstantiationMode :: LocalCopy
191
+ }
192
+
193
+ // Finally, if this is `#[inline(always)]` we're sure to respect
194
+ // that with an inline copy per CGU, but otherwise we'll be
195
+ // creating one copy of this `#[inline]` function which may
196
+ // conflict with upstream crates as it could be an exported
197
+ // symbol.
198
+ let attrs = instance. def . attrs ( tcx) ;
199
+ match attr:: find_inline_attr ( Some ( tcx. sess . diagnostic ( ) ) , & attrs) {
200
+ InlineAttr :: Always => InstantiationMode :: LocalCopy ,
201
+ _ => {
184
202
InstantiationMode :: GloballyShared { may_conflict : true }
185
203
}
186
- } else {
187
- InstantiationMode :: GloballyShared { may_conflict : false }
188
204
}
189
205
}
190
206
TransItem :: Static ( ..) => {
0 commit comments