Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,29 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
match i.kind {
ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => {
let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
let links_to_llvm = link_name.is_some_and(|val| val.as_str().starts_with("llvm."));
if links_to_llvm {
let symbol_name = if let Some(link_name) =
attr::first_attr_value_str_by_name(&i.attrs, sym::link_name)
{
link_name
} else {
i.kind.ident().unwrap().name
};

let name = symbol_name.as_str();
if name.starts_with("llvm.") {
gate!(
self,
link_llvm_intrinsics,
i.span,
"linking to LLVM intrinsics is experimental"
);
} else if name.starts_with("__enzyme_") {
gate!(
self,
link_enzyme_intrinsics,
i.span,
"linking to Enzyme intrinsics is experimental"
);
}
}
ast::ForeignItemKind::TyAlias(..) => {
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::fmt::Debug;
use std::io;
use std::io::Write;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use annotate_snippets::renderer::DEFAULT_TERM_WIDTH;
use annotate_snippets::{AnnotationKind, Group, Origin, Padding, Patch, Renderer, Snippet};
Expand Down Expand Up @@ -46,6 +47,9 @@ pub struct AnnotateSnippetEmitter {
track_diagnostics: bool,
terminal_url: TerminalUrl,
theme: OutputTheme,
/// Whether we've already suggested installing `rust-src`. Shown at most once per compile.
#[setters(skip)]
rust_src_hint_shown: AtomicBool,
}

impl Debug for AnnotateSnippetEmitter {
Expand Down Expand Up @@ -147,6 +151,7 @@ impl AnnotateSnippetEmitter {
track_diagnostics: false,
terminal_url: TerminalUrl::No,
theme: OutputTheme::Ascii,
rust_src_hint_shown: AtomicBool::new(false),
}
}

Expand Down Expand Up @@ -231,6 +236,7 @@ impl AnnotateSnippetEmitter {
group,
&annotation_level,
);
self.maybe_suggest_rust_src(&file.name, sm, &mut group);
// If this is the last annotation for a file, and
// this is the last file, and the first child is a
// "secondary" message, we need to add padding
Expand Down Expand Up @@ -299,6 +305,7 @@ impl AnnotateSnippetEmitter {
group,
&level,
);
self.maybe_suggest_rust_src(&file.name, sm, &mut group);
}
}
}
Expand Down Expand Up @@ -582,6 +589,29 @@ impl AnnotateSnippetEmitter {
}
}

/// If `file_name` is a remapped standard-library source (so its source isn't available
/// locally), append a one-time `help` telling the user to install `rust-src`. Shown at most
/// once per compile session (tracked via `self.rust_src_hint_shown`).
fn maybe_suggest_rust_src<'a>(
&self,
file_name: &FileName,
sm: &Arc<SourceMap>,
group: &mut Group<'a>,
) {
if self.rust_src_hint_shown.load(Ordering::Relaxed)
|| !sm.filename_for_diagnostics(file_name).starts_with("/rustc/")
{
return;
}
self.rust_src_hint_shown.store(true, Ordering::Relaxed);
// `Group::element` consumes `self`, so swap in a cheap placeholder to take ownership.
let owned = std::mem::replace(group, Group::with_level(annotate_snippets::Level::HELP));
*group = owned.element(annotate_snippets::Level::HELP.message(
"the source code for the standard library is not available; \
run `rustup component add rust-src` to make it available",
));
}

fn unannotated_messages<'a>(
&self,
annotations: Vec<Annotation>,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ declare_features! (
(internal, lang_items, "1.0.0", None),
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
(internal, link_cfg, "1.14.0", None),
/// Allows using `#[link_name="__enzyme_*"]`.
(internal, link_enzyme_intrinsics, "CURRENT_RUSTC_VERSION", None),
/// Allows using `?Trait` trait bounds in more contexts.
(internal, more_maybe_bounds, "1.82.0", None),
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,14 @@ impl<'a> FileNameDisplay<'a> {
_ => Cow::from(self.to_string()),
}
}

/// Returns whether the displayed file name starts with `prefix`.
///
/// Avoids allocating in the common case of a valid-UTF-8 path, where
/// `to_string_lossy` borrows rather than allocates.
pub fn starts_with(&self, prefix: &str) -> bool {
self.to_string_lossy().starts_with(prefix)
}
}

impl FileName {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,7 @@ symbols! {
link_args,
link_cfg,
link_dash_arg: "link-arg",
link_enzyme_intrinsics,
link_llvm_intrinsics,
link_name,
link_ordinal,
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/mk/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ TEST_SET2 := --skip=tests --skip=library --skip=tidyselftest

# this intentionally doesn't use `$(BOOTSTRAP)` so we can test the shebang on Windows
ci-msvc-py:
$(Q)$(CFG_SRC_DIR)/x.py test --stage 2 $(TEST_SET1) --skip=src/tools/linkchecker
$(Q)$(CFG_SRC_DIR)/x.py test --stage 2 $(TEST_SET1)
ci-msvc-ps1:
$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 $(TEST_SET2) --skip=src/tools/linkchecker
$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 $(TEST_SET2)
ci-msvc: ci-msvc-py ci-msvc-ps1

## MingW native builders
Expand Down
7 changes: 0 additions & 7 deletions src/bootstrap/src/core/build_steps/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1415,13 +1415,6 @@ impl CommandLineStep for RustcBook {
/// in the "md-doc" directory in the build output directory. Then
/// "rustbook" is used to convert it to HTML.
fn run(self, builder: &Builder<'_>) {
// FIXME: Temporary workaround for https://github.com/rust-lang/rust/issues/158378
// Make sure this workaround doesn't break unit tests on the affected host.
if cfg!(not(test)) && self.target == "i686-pc-windows-msvc" {
eprintln!("WARNING: Skipping rustc book build to work around #158378");
return;
}

let out_base = builder.out.join(self.target).join("md-doc").join("rustc");
t!(fs::create_dir_all(&out_base));
let out_listing = out_base.join("src/lints");
Expand Down
1 change: 0 additions & 1 deletion src/ci/github-actions/jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,6 @@ auto:
--host=
--target=i686-pc-windows-msvc
--enable-profiler
--disable-docs
SCRIPT: python x.py dist bootstrap --include-default-paths
CODEGEN_BACKENDS: llvm
<<: *job-windows
Expand Down
1 change: 0 additions & 1 deletion src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ static DOCS_FALLBACK: &[(&str, &str)] = &[
("-apple-", "aarch64-apple-darwin"),
("aarch64", "aarch64-unknown-linux-gnu"),
("arm-", "aarch64-unknown-linux-gnu"),
("i686-pc-windows", "x86_64-pc-windows-msvc"),
("", "x86_64-unknown-linux-gnu"),
];

Expand Down
27 changes: 27 additions & 0 deletions tests/ui/errors/suggest-rust-src.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// When a diagnostic points into the standard library but its source isn't
// available locally, rustc can't render the snippet. In that case it should
// suggest installing the `rust-src` component. See #156402.
//
// We simulate the "std source unavailable" situation (as happens with a `rustup`
// toolchain that doesn't have `rust-src` installed) by remapping the rust-src
// base and disabling translation back to the local path.
//@ compile-flags: -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no
//
// The line:col of the remapped std path is volatile, so normalise it. (The
// `$SRC_DIR` normalisation doesn't kick in because the path is remapped.)
//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL"

use std::thread;

struct Worker {
thread: thread::JoinHandle<()>,
}

impl Drop for Worker {
fn drop(&mut self) {
self.thread.join().unwrap();
//~^ ERROR cannot move out of `self.thread` which is behind a mutable reference
}
}

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/errors/suggest-rust-src.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0507]: cannot move out of `self.thread` which is behind a mutable reference
--> $DIR/suggest-rust-src.rs:LL:COL
|
LL | self.thread.join().unwrap();
| ^^^^^^^^^^^ ------ `self.thread` moved due to this method call
| |
| move occurs because `self.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait
|
note: `JoinHandle::<T>::join` takes ownership of the receiver `self`, which moves `self.thread`
--> $SRC_DIR/std/src/thread/join_handle.rs:LL:COL
= help: the source code for the standard library is not available; run `rustup component add rust-src` to make it available

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0507`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ check-pass
// gate-test-link_enzyme_intrinsics
#![feature(link_enzyme_intrinsics)]

unsafe extern "C" {
fn __enzyme_autodiff();
fn __enzyme_fwddiff();
fn __enzyme_augmentfwd();
fn __enzyme_reverse();
#[link_name = "__enzyme_autodiff"]
fn autodiff();

static __enzyme_dup: i32;
#[link_name = "__enzyme_dup"]
static ENZYME_DUP: i32;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// gate-test-link_enzyme_intrinsics

unsafe extern "C" {
fn __enzyme_autodiff();
//~^ ERROR linking to Enzyme intrinsics is experimental

fn __enzyme_fwddiff();
//~^ ERROR linking to Enzyme intrinsics is experimental

fn __enzyme_augmentfwd();
//~^ ERROR linking to Enzyme intrinsics is experimental

fn __enzyme_reverse();
//~^ ERROR linking to Enzyme intrinsics is experimental

#[link_name = "__enzyme_autodiff"]
fn autodiff();
//~^ ERROR linking to Enzyme intrinsics is experimental

static __enzyme_dup: i32;
//~^ ERROR linking to Enzyme intrinsics is experimental

#[link_name = "__enzyme_dup"]
static ENZYME_DUP: i32;
//~^ ERROR linking to Enzyme intrinsics is experimental

static enzyme_dup: i32;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:4:5
|
LL | fn __enzyme_autodiff();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:7:5
|
LL | fn __enzyme_fwddiff();
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:10:5
|
LL | fn __enzyme_augmentfwd();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:13:5
|
LL | fn __enzyme_reverse();
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:17:5
|
LL | fn autodiff();
| ^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:20:5
|
LL | static __enzyme_dup: i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: linking to Enzyme intrinsics is experimental
--> $DIR/feature-gate-link-enzyme-intrinsics-no-gate.rs:24:5
|
LL | static ENZYME_DUP: i32;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(link_enzyme_intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0658`.
33 changes: 33 additions & 0 deletions tests/ui/higher-ranked/hr-fn-ptr-trait-impl-mismatch-29061.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/29061>.
//!
//! A trait implemented for a higher-ranked fn pointer is not implemented for a fn pointer
//! with a specific lifetime, and vice versa. The errors now spell out which form the impl
//! applies to instead of just saying the bound is unsatisfied.

//@ edition: 2024

#![allow(dead_code)]

fn x(_: &()) {}

trait HR {}
impl HR for fn(&()) {}
fn hr<T: HR>(_: T) {}

trait NotHR {}
impl<'a> NotHR for fn(&'a ()) {}
fn not_hr<T: NotHR>(_: T) {}

fn a<'a>() {
let not_hr_func: fn(&'a ()) = x;
let hr_func: fn(&()) = x;
let hr_func2: for<'b> fn(&'b ()) = x;
hr(not_hr_func);
//~^ ERROR implementation of `HR` is not general enough
not_hr(hr_func);
//~^ ERROR implementation of `NotHR` is not general enough
not_hr(hr_func2);
//~^ ERROR implementation of `NotHR` is not general enough
}

fn main() {}
Loading
Loading