Skip to content

Commit 78613dc

Browse files
Auto merge of #150779 - Kobzol:rollup-mg8Flxz, r=Kobzol
Rollup of 5 pull requests Successful merges: - #150696 (enrich error info when tries to dlopen Enzyme) - #150721 (Deprecated doc intra link) - #150747 (tests/ui/runtime/on-broken-pipe/with-rustc_main.rs: Not needed so remove) - #150761 (rustc book: fix grammar) - #150775 (Move issue-12660 to 'ui/cross-crate/ with a descriptive name) r? @ghost
2 parents fc546b9 + 99bd508 commit 78613dc

19 files changed

Lines changed: 236 additions & 53 deletions

File tree

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,34 @@ impl AttributeExt for Attribute {
235235
}
236236
}
237237

238+
fn deprecation_note(&self) -> Option<Symbol> {
239+
match &self.kind {
240+
AttrKind::Normal(normal) if normal.item.path == sym::deprecated => {
241+
let meta = &normal.item;
242+
243+
// #[deprecated = "..."]
244+
if let Some(s) = meta.value_str() {
245+
return Some(s);
246+
}
247+
248+
// #[deprecated(note = "...")]
249+
if let Some(list) = meta.meta_item_list() {
250+
for nested in list {
251+
if let Some(mi) = nested.meta_item()
252+
&& mi.path == sym::note
253+
&& let Some(s) = mi.value_str()
254+
{
255+
return Some(s);
256+
}
257+
}
258+
}
259+
260+
None
261+
}
262+
_ => None,
263+
}
264+
}
265+
238266
fn doc_resolution_scope(&self) -> Option<AttrStyle> {
239267
match &self.kind {
240268
AttrKind::DocComment(..) => Some(self.style),
@@ -277,6 +305,7 @@ impl Attribute {
277305

278306
pub fn may_have_doc_links(&self) -> bool {
279307
self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
308+
|| self.deprecation_note().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
280309
}
281310

282311
/// Extracts the MetaItem from inside this Attribute.
@@ -873,6 +902,11 @@ pub trait AttributeExt: Debug {
873902
/// * `#[doc(...)]` returns `None`.
874903
fn doc_str(&self) -> Option<Symbol>;
875904

905+
/// Returns the deprecation note if this is deprecation attribute.
906+
/// * `#[deprecated = "note"]` returns `Some("note")`.
907+
/// * `#[deprecated(note = "note", ...)]` returns `Some("note")`.
908+
fn deprecation_note(&self) -> Option<Symbol>;
909+
876910
fn is_proc_macro_attr(&self) -> bool {
877911
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
878912
.iter()

compiler/rustc_codegen_llvm/messages.ftl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup?
1+
codegen_llvm_autodiff_component_missing = autodiff backend not found in the sysroot: {$err}
2+
.note = it will be distributed via rustup in the future
3+
4+
codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend: {$err}
25
36
codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable
47
codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml

compiler/rustc_codegen_llvm/src/errors.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
3434

3535
#[derive(Diagnostic)]
3636
#[diag(codegen_llvm_autodiff_component_unavailable)]
37-
pub(crate) struct AutoDiffComponentUnavailable;
37+
pub(crate) struct AutoDiffComponentUnavailable {
38+
pub err: String,
39+
}
40+
41+
#[derive(Diagnostic)]
42+
#[diag(codegen_llvm_autodiff_component_missing)]
43+
#[note]
44+
pub(crate) struct AutoDiffComponentMissing {
45+
pub err: String,
46+
}
3847

3948
#[derive(Diagnostic)]
4049
#[diag(codegen_llvm_autodiff_without_lto)]

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,14 @@ impl CodegenBackend for LlvmCodegenBackend {
249249

250250
use crate::back::lto::enable_autodiff_settings;
251251
if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) {
252-
if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) {
253-
sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable);
252+
match llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) {
253+
Ok(_) => {}
254+
Err(llvm::EnzymeLibraryError::NotFound { err }) => {
255+
sess.dcx().emit_fatal(crate::errors::AutoDiffComponentMissing { err });
256+
}
257+
Err(llvm::EnzymeLibraryError::LoadFailed { err }) => {
258+
sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { err });
259+
}
254260
}
255261
enable_autodiff_settings(&sess.opts.unstable_opts.autodiff);
256262
}

compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ pub(crate) mod Enzyme_AD {
153153
fn load_ptr_by_symbol_mut_void(
154154
lib: &libloading::Library,
155155
bytes: &[u8],
156-
) -> Result<*mut c_void, Box<dyn std::error::Error>> {
156+
) -> Result<*mut c_void, libloading::Error> {
157157
unsafe {
158158
let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?;
159159
// libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some
@@ -192,15 +192,27 @@ pub(crate) mod Enzyme_AD {
192192

193193
static ENZYME_INSTANCE: OnceLock<Mutex<EnzymeWrapper>> = OnceLock::new();
194194

195+
#[derive(Debug)]
196+
pub(crate) enum EnzymeLibraryError {
197+
NotFound { err: String },
198+
LoadFailed { err: String },
199+
}
200+
201+
impl From<libloading::Error> for EnzymeLibraryError {
202+
fn from(err: libloading::Error) -> Self {
203+
Self::LoadFailed { err: format!("{err:?}") }
204+
}
205+
}
206+
195207
impl EnzymeWrapper {
196208
/// Initialize EnzymeWrapper with the given sysroot if not already initialized.
197209
/// Safe to call multiple times - subsequent calls are no-ops due to OnceLock.
198210
pub(crate) fn get_or_init(
199211
sysroot: &rustc_session::config::Sysroot,
200-
) -> Result<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
212+
) -> Result<MutexGuard<'static, Self>, EnzymeLibraryError> {
201213
let mtx: &'static Mutex<EnzymeWrapper> = ENZYME_INSTANCE.get_or_try_init(|| {
202214
let w = Self::call_dynamic(sysroot)?;
203-
Ok::<_, Box<dyn std::error::Error>>(Mutex::new(w))
215+
Ok::<_, EnzymeLibraryError>(Mutex::new(w))
204216
})?;
205217

206218
Ok(mtx.lock().unwrap())
@@ -351,7 +363,7 @@ pub(crate) mod Enzyme_AD {
351363
#[allow(non_snake_case)]
352364
fn call_dynamic(
353365
sysroot: &rustc_session::config::Sysroot,
354-
) -> Result<Self, Box<dyn std::error::Error>> {
366+
) -> Result<Self, EnzymeLibraryError> {
355367
let enzyme_path = Self::get_enzyme_path(sysroot)?;
356368
let lib = unsafe { libloading::Library::new(enzyme_path)? };
357369

@@ -416,7 +428,7 @@ pub(crate) mod Enzyme_AD {
416428
})
417429
}
418430

419-
fn get_enzyme_path(sysroot: &Sysroot) -> Result<String, String> {
431+
fn get_enzyme_path(sysroot: &Sysroot) -> Result<String, EnzymeLibraryError> {
420432
let llvm_version_major = unsafe { LLVMRustVersionMajor() };
421433

422434
let path_buf = sysroot
@@ -434,15 +446,19 @@ pub(crate) mod Enzyme_AD {
434446
.map(|p| p.join("lib").display().to_string())
435447
.collect::<Vec<String>>()
436448
.join("\n* ");
437-
format!(
438-
"failed to find a `libEnzyme-{llvm_version_major}` folder \
449+
EnzymeLibraryError::NotFound {
450+
err: format!(
451+
"failed to find a `libEnzyme-{llvm_version_major}` folder \
439452
in the sysroot candidates:\n* {candidates}"
440-
)
453+
),
454+
}
441455
})?;
442456

443457
Ok(path_buf
444458
.to_str()
445-
.ok_or_else(|| format!("invalid UTF-8 in path: {}", path_buf.display()))?
459+
.ok_or_else(|| EnzymeLibraryError::LoadFailed {
460+
err: format!("invalid UTF-8 in path: {}", path_buf.display()),
461+
})?
446462
.to_string())
447463
}
448464
}

compiler/rustc_hir/src/hir.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,14 @@ impl AttributeExt for Attribute {
14091409
}
14101410
}
14111411

1412+
#[inline]
1413+
fn deprecation_note(&self) -> Option<Symbol> {
1414+
match &self {
1415+
Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => deprecation.note,
1416+
_ => None,
1417+
}
1418+
}
1419+
14121420
fn is_automatically_derived_attr(&self) -> bool {
14131421
matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
14141422
}

compiler/rustc_resolve/src/rustdoc.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,17 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool {
410410
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
411411
/// Must return at least the same links as it, but may add some more links on top of that.
412412
pub(crate) fn attrs_to_preprocessed_links<A: AttributeExt + Clone>(attrs: &[A]) -> Vec<Box<str>> {
413-
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
414-
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
413+
let (doc_fragments, other_attrs) =
414+
attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), false);
415+
let mut doc =
416+
prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap_or_default();
417+
418+
for attr in other_attrs {
419+
if let Some(note) = attr.deprecation_note() {
420+
doc += note.as_str();
421+
doc += "\n";
422+
}
423+
}
415424

416425
parse_links(&doc)
417426
}

src/doc/rustc/src/remap-source-paths.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
`rustc` supports remapping source paths prefixes **as a best effort** in all compiler generated
44
output, including compiler diagnostics, debugging information, macro expansions, etc.
55

6-
This is useful for normalizing build products, for example by removing the current directory
6+
This is useful for normalizing build products, for example, by removing the current directory
77
out of the paths emitted into object files.
88

99
The remapping is done via the `--remap-path-prefix` option.
@@ -41,7 +41,7 @@ This example replaces all occurrences of `/home/user/project` in emitted paths w
4141

4242
## Caveats and Limitations
4343

44-
### Linkers generated paths
44+
### Paths generated by linkers
4545

4646
On some platforms like `x86_64-pc-windows-msvc`, the linker may embed absolute host paths and compiler
4747
arguments into debug info files (like `.pdb`) independently of `rustc`.
@@ -54,7 +54,7 @@ The `--remap-path-prefix` option does not affect these linker-generated paths.
5454
### Textual replacement only
5555

5656
The remapping is strictly textual and does not account for different path separator conventions across
57-
platforms. Care must be taken when specifying prefixes, especially on Windows where both `/` and `\` may
57+
platforms. Care must be taken when specifying prefixes, especially on Windows, where both `/` and `\` may
5858
appear in paths.
5959

6060
### External tools

src/librustdoc/clean/types.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{fmt, iter};
77
use arrayvec::ArrayVec;
88
use itertools::Either;
99
use rustc_abi::{ExternAbi, VariantIdx};
10+
use rustc_ast::attr::AttributeExt;
1011
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1112
use rustc_data_structures::thin_vec::ThinVec;
1213
use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation, DocAttribute};
@@ -450,7 +451,16 @@ impl Item {
450451
}
451452

452453
pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
454+
let deprecation_notes = self
455+
.attrs
456+
.other_attrs
457+
.iter()
458+
.filter_map(|attr| attr.deprecation_note().map(|_| attr.span()));
459+
453460
span_of_fragments(&self.attrs.doc_strings)
461+
.into_iter()
462+
.chain(deprecation_notes)
463+
.reduce(|a, b| a.to(b))
454464
.unwrap_or_else(|| self.span(tcx).map_or(DUMMY_SP, |span| span.inner()))
455465
}
456466

src/librustdoc/html/markdown.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ pub(crate) struct MarkdownWithToc<'a> {
111111
}
112112
/// A tuple struct like `Markdown` that renders the markdown escaping HTML tags
113113
/// and includes no paragraph tags.
114-
pub(crate) struct MarkdownItemInfo<'a>(pub(crate) &'a str, pub(crate) &'a mut IdMap);
114+
pub(crate) struct MarkdownItemInfo<'a> {
115+
pub(crate) content: &'a str,
116+
pub(crate) links: &'a [RenderedLink],
117+
pub(crate) ids: &'a mut IdMap,
118+
}
115119
/// A tuple struct like `Markdown` that renders only the first paragraph.
116120
pub(crate) struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
117121

@@ -1459,15 +1463,28 @@ impl MarkdownWithToc<'_> {
14591463
}
14601464
}
14611465

1462-
impl MarkdownItemInfo<'_> {
1466+
impl<'a> MarkdownItemInfo<'a> {
1467+
pub(crate) fn new(content: &'a str, links: &'a [RenderedLink], ids: &'a mut IdMap) -> Self {
1468+
Self { content, links, ids }
1469+
}
1470+
14631471
pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result {
1464-
let MarkdownItemInfo(md, ids) = self;
1472+
let MarkdownItemInfo { content: md, links, ids } = self;
14651473

14661474
// This is actually common enough to special-case
14671475
if md.is_empty() {
14681476
return Ok(());
14691477
}
1470-
let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
1478+
1479+
let replacer = move |broken_link: BrokenLink<'_>| {
1480+
links
1481+
.iter()
1482+
.find(|link| *link.original_text == *broken_link.reference)
1483+
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
1484+
};
1485+
1486+
let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(replacer));
1487+
let p = p.into_offset_iter();
14711488

14721489
// Treat inline HTML as plain text.
14731490
let p = p.map(|event| match event.0 {
@@ -1477,6 +1494,7 @@ impl MarkdownItemInfo<'_> {
14771494

14781495
ids.handle_footnotes(|ids, existing_footnotes| {
14791496
let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1);
1497+
let p = SpannedLinkReplacer::new(p, links);
14801498
let p = footnotes::Footnotes::new(p, existing_footnotes);
14811499
let p = TableWrapper::new(p.map(|(ev, _)| ev));
14821500
let p = p.filter(|event| {

0 commit comments

Comments
 (0)