Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Implemented a linkage attribute for functions and foreign statics. - #9966

Closed
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage
Closed

Implemented a linkage attribute for functions and foreign statics.#9966
eddyb wants to merge 1 commit into
rust-lang:masterfrom
eddyb:attr-linkage

Conversation

@eddyb

Copy link
Copy Markdown
Contributor

Closes#7196 and obsoletes #9945 (I've reused the test from the latter, with the added linkage(external) attribute).
The subset of allowed linkages is left to be decided by the reviewers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline(always)? To check that linkage(external) is forcing it to stay around? (Worth a comment, probably.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the test behaves the same (when toggling linkage(external)), independently of --opt-level.

@huonw

Copy link
Copy Markdown
Contributor

What happens for (e.g.) #[linkage(dll_export)] on Linux?

@eddyb

Copy link
Copy Markdown
ContributorAuthor

That's odd... LLVM doesn't error when using dll_export on Linux. However, I expect that to be a compatibility feature, since the test works with dll_export as it does with external.

@alexcrichton

Copy link
Copy Markdown
Member

I'm a little uneasy about this change. Could you elaborate a little more on what the main purpose for these is going to be?

I'm generally of the opinion that we should be able to infer as much of this as possible. We already infer whether to make a function externally visible (or at least we should be correctly doing so). You can very easily shoot yourself in the foot by tinkering with these linkage attributes too much, which rust strives to make it very hard to do so.

This seems to be like more of a bug in other portions of the language than to attempt to allow this on a per-item basis. Our management of linkage of symbols is already hairy enough as-is, and throwing this in the mix could very easily produce unexpected results. I personally don't think that we should have the weak_linkage or link_name attributes, I think that we're starting to allow too much power for such small use cases.

I still believe that all use cases should be encodable in some form of rust, but not necessarily through the use of attributes. Things like:

  • If you want an internal linkage function, you shouldn't make it accessible from the outside world
  • If you want an external linkage function, you should make it accessible from the outside world (pub from the root)
  • If you declare extern "C", we probably shouldn't flag that as internal (seeing how you explicitly wrote the extern on it)
  • It's not clear to me what dll import/export do for windows, so I would need to understand more about them before saying how they should be encoded in rust

Again though, I could just be unaware of perfectly legitimate use cases which definitely need fine-grained control over linkage. My perference would be to have a different way to encode this type of use other than being able to specify the linkage per-item, though.

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: A private extern "C" function should definitely be internal, it's the way to declare a function with a C ABI. You don't want internal functions you pass as function pointers to C to be external.

@alexcrichton

Copy link
Copy Markdown
Member

I was looking over the list of linkages that llvm provides, and this is what I ended up noticing:

  • private - this was pretty much the same as internal, I don't personally see why rust source would want this and not internal
  • linker_private - same as above
  • internal - this is quite useful, and I believe that the visibility rust has maps well to this, so I'm not sure why you'd want to explicitly flag this on a function
  • available_externally - this is currently used for inlining globals, but it's not clear to me why you would want to do this manually with a function
  • linkonce - This would be very useful for when we instantiate generic functions, but I don't see why you'd want to place this manually on a function
  • weak - It's not clear that this is necessary, if you want this in rust it seems like you may want extern_weak, but there may be a use case here that I'm not seeing.
  • common - It's not clear to me that we'd want this
  • appending - only works if we use llvm arrays, which I don't believe we are currently doing
  • extern_weak - This is useful sometimes. I'm not sure it totally makes sense to put on a function though, it may only be applicable to statics.
  • *_odr - like generic instantiation, this seems like the compiler should be emitting this instead of users explicitly on fuctions
  • external - very useful, but this is encoded with visibility
  • dllexport and dllimport - I'm still not quite sure what these do, so I wouldn't be able to comment much on them.

From this list, it really seems like the useful ones which you'd want to apply are weak and dllimport/export (although I don't know what they do, so perhaps they are encodable in other rust-isms). Overally, it's not clear to me that we're gaining much by allowing such fine-grained control of linkage attributes. The existing cases where a different linkage is desired seem like a bug that should be fixed or it's wontfix behavior.

That being said, I could certainly be unaware of other use cases!

@thestinger

Copy link
Copy Markdown
Contributor

@alexcrichton: linkonce isn't useful without translation units that are built together either with static linking or via LTO. It could discard copies of the symbol from within the same crate, but we never have those.

@thestinger

Copy link
Copy Markdown
Contributor

The changes implemented by #9945 have landed, so I think the use case this was meant for is now well covered. I think the Windows issue is likely separate, I don't really understand why external wouldn't be the same thing.

We can revisit this in the future if a use case comes up.

@eddyb
eddyb deleted the attr-linkage branch February 6, 2016 11:45
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 17, 2022
…=xFrednet
Fix manual_let_else produces a wrong suggestion with or-patterns
Fixrust-lang#9938
changelog: Sugg: [`manual_let_else`]: Suggestions for or-patterns now include required brackets.
[rust-lang#9966](rust-lang/rust-clippy#9966)
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9966: fix: Determine expected parameters from expected return in calls r=flodiebold a=flodiebold
Second attempt 😅 Fixesrust-lang#9560 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
Chalk can introduce new type variables when doing lazy normalization, so
we have to do the proper 'fudging' after all.
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
9975: minor: Fix panic caused by rust-lang#9966 r=flodiebold a=flodiebold
Chalk can introduce new type variables when doing lazy normalization, so we have to do the proper 'fudging' after all.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for DllExport on Windows

4 participants

@eddyb@huonw@alexcrichton@thestinger