Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
fc4056e
Constify `ManuallyDrop::take`
nxsaken Nov 9, 2025
264c6d4
Constify `mem::take`
nxsaken Nov 9, 2025
1d9be66
Add tracking issue number
nxsaken Nov 10, 2025
63f4b36
provide an error if an autodiff user does not set in their Cargo.toml
ZuseZ4 Nov 12, 2025
c8bae8c
add a test to verify a good error for enabling autodiff without lto
ZuseZ4 Nov 12, 2025
4996edc
add note to `lines` docs about empty str behavior
msmoiz Nov 13, 2025
e628b05
update language from "no lines" to "empty iterator"
msmoiz Nov 14, 2025
64f0579
Run wasm32-wasip1 codegen tests in PR CI
saethlin Nov 15, 2025
c287f6e
compiletest: Avoid race condition in file deletion
jamie-osec Nov 16, 2025
7194c92
add larger test for `proc_macro` `FromStr` implementations
cyrgani Nov 4, 2025
70a0af3
Remove jsha from notifications for rustdoc HTML
jsha Nov 17, 2025
018140b
Rollup merge of #148505 - cyrgani:pm-tests, r=madsmtm
Zalathar Nov 17, 2025
6c8a265
Rollup merge of #148752 - nxsaken:const_manually_drop_take, r=scottmcm
Zalathar Nov 17, 2025
968cfd3
Rollup merge of #148757 - nxsaken:const_mem_take, r=scottmcm
Zalathar Nov 17, 2025
9ef700c
Rollup merge of #148855 - ZuseZ4:autodiff-lto-error, r=bjorn3
Zalathar Nov 17, 2025
2812598
Rollup merge of #148912 - msmoiz:main, r=scottmcm
Zalathar Nov 17, 2025
8fccebd
Rollup merge of #148958 - saethlin:32bit-codegen-pr, r=kobzol
Zalathar Nov 17, 2025
9e794a2
Rollup merge of #149004 - clubby789:compiletest-delete-safe, r=jieyouxu
Zalathar Nov 17, 2025
f51d131
Rollup merge of #149008 - jsha:jsha-unwatch-doc-html, r=jieyouxu
Zalathar Nov 17, 2025
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
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable
codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml

codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
}
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_without_lto)]
pub(crate) struct AutoDiffWithoutLto;

#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_without_enable)]
pub(crate) struct AutoDiffWithoutEnable;
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::abi::FnAbiLlvmExt;
use crate::builder::Builder;
use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call};
use crate::context::CodegenCx;
use crate::errors::AutoDiffWithoutEnable;
use crate::errors::{AutoDiffWithoutEnable, AutoDiffWithoutLto};
use crate::llvm::{self, Metadata, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg;
Expand Down Expand Up @@ -1146,6 +1146,9 @@ fn codegen_autodiff<'ll, 'tcx>(
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
}
if tcx.sess.lto() != rustc_session::config::Lto::Fat {
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
}

let fn_args = instance.args;
let callee_ty = instance.ty(tcx, bx.typing_env());
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,14 +594,6 @@ impl Session {

/// Calculates the flavor of LTO to use for this compilation.
pub fn lto(&self) -> config::Lto {
// Autodiff currently requires fat-lto to have access to the llvm-ir of all (indirectly) used functions and types.
// fat-lto is the easiest solution to this requirement, but quite expensive.
// FIXME(autodiff): Make autodiff also work with embed-bc instead of fat-lto.
// Don't apply fat-lto to proc-macro crates as they cannot use fat-lto without -Zdylib-lto
if self.opts.autodiff_enabled() && !self.opts.crate_types.contains(&CrateType::ProcMacro) {
return config::Lto::Fat;
}

// If our target has codegen requirements ignore the command line
if self.target.requires_lto {
return config::Lto::Fat;
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/mem/manually_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,9 @@ impl<T> ManuallyDrop<T> {
///
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
#[stable(feature = "manually_drop_take", since = "1.42.0")]
#[rustc_const_unstable(feature = "const_manually_drop_take", issue = "148773")]
#[inline]
pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
pub const unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
// SAFETY: we are reading from a reference, which is guaranteed
// to be valid for reads.
unsafe { ptr::read(&slot.value) }
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,8 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
/// ```
#[inline]
#[stable(feature = "mem_take", since = "1.40.0")]
pub fn take<T: Default>(dest: &mut T) -> T {
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
pub const fn take<T: [const] Default>(dest: &mut T) -> T {
replace(dest, T::default())
}

Expand Down
11 changes: 11 additions & 0 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,8 @@ impl str {
/// ending will return the same lines as an otherwise identical string
/// without a final line ending.
///
/// An empty string returns an empty iterator.
///
/// # Examples
///
/// Basic usage:
Expand Down Expand Up @@ -1281,6 +1283,15 @@ impl str {
///
/// assert_eq!(None, lines.next());
/// ```
///
/// An empty string returns an empty iterator:
///
/// ```
/// let text = "";
/// let mut lines = text.lines();
///
/// assert_eq!(lines.next(), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn lines(&self) -> Lines<'_> {
Expand Down
8 changes: 8 additions & 0 deletions src/ci/docker/host-x86_64/pr-check-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
mingw-w64 \
&& rm -rf /var/lib/apt/lists/*

RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/wasi-sdk-27.0-x86_64-linux

ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3"

COPY scripts/sccache.sh /scripts/
Expand All @@ -30,6 +34,10 @@ ENV SCRIPT \
python3 ../x.py check && \
python3 ../x.py clippy ci --stage 2 && \
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
# Elsewhere, we run all tests for the host. A number of codegen tests are sensitive to the target pointer
# width, for example because they mention a usize. wasm32-wasip1 in test-various, so using it here can't make
# PR CI more strict than full CI.
python3 ../x.py test --stage 1 tests/codegen-llvm --target wasm32-wasip1 && \
python3 ../x.py test --stage 1 src/tools/compiletest && \
python3 ../x.py doc bootstrap --stage 1 && \
# Build both public and internal documentation.
Expand Down
9 changes: 4 additions & 5 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2766,12 +2766,11 @@ impl<'test> TestCx<'test> {
.map_err(|err| format!("failed to load expected output from `{}`: {}", path, err))
}

/// Attempts to delete a file, succeeding if the file does not exist.
fn delete_file(&self, file: &Utf8Path) {
if !file.exists() {
// Deleting a nonexistent file would error.
return;
}
if let Err(e) = fs::remove_file(file.as_std_path()) {
if let Err(e) = fs::remove_file(file.as_std_path())
&& e.kind() != io::ErrorKind::NotFound
{
self.fatal(&format!("failed to delete `{}`: {}", file, e,));
}
}
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/autodiff/no_lto_flag.no_lto.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: using the autodiff feature requires setting `lto="fat"` in your Cargo.toml

error: aborting due to 1 previous error

31 changes: 31 additions & 0 deletions tests/ui/autodiff/no_lto_flag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//@ needs-enzyme
//@ no-prefer-dynamic
//@ revisions: with_lto no_lto
//@[with_lto] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
//@[no_lto] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=thin

#![feature(autodiff)]
//@[no_lto] build-fail
//@[with_lto] build-pass

// Autodiff requires users to enable lto=fat (for now).
// In the past, autodiff did not run if users forget to enable fat-lto, which caused functions to
// returning zero-derivatives. That's obviously wrong and confusing to users. We now added a check
// which will abort compilation instead.

use std::autodiff::autodiff_reverse;
//[no_lto]~? ERROR using the autodiff feature requires setting `lto="fat"` in your Cargo.toml

#[autodiff_reverse(d_square, Duplicated, Active)]
fn square(x: &f64) -> f64 {
*x * *x
}

fn main() {
let xf64: f64 = std::hint::black_box(3.0);

let mut df_dxf64: f64 = std::hint::black_box(0.0);

let _output_f64 = d_square(&xf64, &mut df_dxf64, 1.0);
assert_eq!(6.0, df_dxf64);
}
143 changes: 143 additions & 0 deletions tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use std::fmt::Debug;
use std::panic::catch_unwind;
use std::str::FromStr;

use proc_macro::*;

use self::Mode::*;

// FIXME: all cases should become `NormalOk` or `NormalErr`
#[derive(PartialEq, Clone, Copy)]
enum Mode {
NormalOk,
NormalErr,
OtherError,
OtherWithPanic,
}

fn parse<T>(s: &str, mode: Mode)
where
T: FromStr<Err = LexError> + Debug,
{
match mode {
NormalOk => {
let t = T::from_str(s);
println!("{:?}", t);
assert!(t.is_ok());
}
NormalErr => {
let t = T::from_str(s);
println!("{:?}", t);
assert!(t.is_err());
}
OtherError => {
println!("{:?}", T::from_str(s));
}
OtherWithPanic => {
if catch_unwind(|| println!("{:?}", T::from_str(s))).is_ok() {
eprintln!("{s} did not panic");
}
}
}
}

fn stream(s: &str, mode: Mode) {
parse::<TokenStream>(s, mode);
}

fn lit(s: &str, mode: Mode) {
parse::<Literal>(s, mode);
if mode == NormalOk {
let Ok(lit) = Literal::from_str(s) else {
panic!("literal was not ok");
};
let Ok(stream) = TokenStream::from_str(s) else {
panic!("tokenstream was not ok, but literal was");
};
let Some(tree) = stream.into_iter().next() else {
panic!("tokenstream should have a tokentree");
};
if let TokenTree::Literal(tokenstream_lit) = tree {
assert_eq!(lit.to_string(), tokenstream_lit.to_string());
}
}
}

pub fn run() {
// returns Ok(valid instance)
lit("123", NormalOk);
lit("\"ab\"", NormalOk);
lit("\'b\'", NormalOk);
lit("'b'", NormalOk);
lit("b\"b\"", NormalOk);
lit("c\"b\"", NormalOk);
lit("cr\"b\"", NormalOk);
lit("b'b'", NormalOk);
lit("256u8", NormalOk);
lit("-256u8", NormalOk);
stream("-256u8", NormalOk);
lit("0b11111000000001111i16", NormalOk);
lit("0xf32", NormalOk);
lit("0b0f32", NormalOk);
lit("2E4", NormalOk);
lit("2.2E-4f64", NormalOk);
lit("18u8E", NormalOk);
lit("18.0u8E", NormalOk);
lit("cr#\"// /* // \n */\"#", NormalOk);
lit("'\\''", NormalOk);
lit("'\\\''", NormalOk);
lit(&format!("r{0}\"a\"{0}", "#".repeat(255)), NormalOk);
stream("fn main() { println!(\"Hello, world!\") }", NormalOk);
stream("18.u8E", NormalOk);
stream("18.0f32", NormalOk);
stream("18.0f34", NormalOk);
stream("18.bu8", NormalOk);
stream("3//\n4", NormalOk);
stream(
"\'c\'/*\n
*/",
NormalOk,
);
stream("/*a*/ //", NormalOk);

println!("### ERRORS");

// returns Err(LexError)
lit("\'c\'/**/", NormalErr);
lit(" 0", NormalErr);
lit("0 ", NormalErr);
lit("0//", NormalErr);
lit("3//\n4", NormalErr);
lit("18.u8E", NormalErr);
lit("/*a*/ //", NormalErr);
// FIXME: all of the cases below should return an Err and emit no diagnostics, but don't yet.

// emits diagnostics and returns LexError
lit("r'r'", OtherError);
lit("c'r'", OtherError);

// emits diagnostic and returns a seemingly valid tokenstream
stream("r'r'", OtherError);
stream("c'r'", OtherError);

for parse in [stream as fn(&str, Mode), lit] {
// emits diagnostic(s), then panics
parse("1 ) 2", OtherWithPanic);
parse("( x [ ) ]", OtherWithPanic);
parse("r#", OtherWithPanic);

// emits diagnostic(s), then returns Ok(Literal { kind: ErrWithGuar, .. })
parse("0b2", OtherError);
parse("0bf32", OtherError);
parse("0b0.0f32", OtherError);
parse("'\''", OtherError);
parse(
"'
'", OtherError,
);
parse(&format!("r{0}\"a\"{0}", "#".repeat(256)), OtherWithPanic);

// emits diagnostic, then, when parsing as a lit, returns LexError, otherwise ErrWithGuar
parse("/*a*/ 0b2 //", OtherError);
}
}
11 changes: 11 additions & 0 deletions tests/ui/proc-macro/auxiliary/nonfatal-parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extern crate proc_macro;
use proc_macro::*;

#[path = "nonfatal-parsing-body.rs"]
mod body;

#[proc_macro]
pub fn run(_: TokenStream) -> TokenStream {
body::run();
TokenStream::new()
}
19 changes: 19 additions & 0 deletions tests/ui/proc-macro/nonfatal-parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ proc-macro: nonfatal-parsing.rs
//@ needs-unwind
//@ edition: 2024
//@ dont-require-annotations: ERROR
//@ ignore-backends: gcc
// FIXME: should be a run-pass test once invalidly parsed tokens no longer result in diagnostics

extern crate proc_macro;
extern crate nonfatal_parsing;

#[path = "auxiliary/nonfatal-parsing-body.rs"]
mod body;

fn main() {
nonfatal_parsing::run!();
// FIXME: enable this once the standalone backend exists
// https://github.com/rust-lang/rust/issues/130856
// body::run();
}
Loading
Loading