Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2f4813f
Stabilize `vec_deque_pop_if`
GrigorenkoPV Aug 19, 2025
acd0294
btree: cleanup difference, intersection, is_subset
hkBst Oct 17, 2025
360b38c
Fix device code generation, to account for an implicit dyn_ptr argument.
ZuseZ4 Sep 1, 2025
ff5440e
Fix incorrect precedence caused by range expression
chenyukang Nov 6, 2025
d956fa1
style: Update doctests for `highest_one` and `lowest_one`
sorairolake Nov 5, 2025
72cec24
Fix mismatched brackets in generated .dir-locals.el
TomFryersMidsummer Nov 6, 2025
e77e5d1
fix dev guide link in rustc_query_system/dep_graph/README.MD
vyacheslavhere Nov 6, 2025
893f0d2
core docs: add notes about availability of `Atomic*::from_mut_slice`
WaffleLapkin Nov 6, 2025
3edd25f
Add typo suggestion for a misspelt Cargo environment variable
chenyukang Nov 6, 2025
eec36b3
update release notes
pietroalbini Nov 6, 2025
b975c57
Sync str::rsplit_once example with str::split_once
AMDmi3 Nov 6, 2025
62ccf14
add check if macro from expansion
Kivooeo Oct 6, 2025
c637939
Rollup merge of #145768 - ZuseZ4:offload-device, r=oli-obk
jhpratt Nov 7, 2025
47eeb00
Rollup merge of #145992 - GrigorenkoPV:stabilize/vec_deque_pop_if, r=…
jhpratt Nov 7, 2025
7af1ee3
Rollup merge of #147416 - Kivooeo:ice-fix23456, r=fmease
jhpratt Nov 7, 2025
4ad5a39
Rollup merge of #147808 - hkBst:btree-3, r=joboet
jhpratt Nov 7, 2025
3d765e3
Rollup merge of #148520 - sorairolake:update-lowest-highest-one-docte…
jhpratt Nov 7, 2025
3186f21
Rollup merge of #148559 - chenyukang:yukang-fix-148439-env, r=Kivooeo
jhpratt Nov 7, 2025
3f1bce5
Rollup merge of #148567 - chenyukang:yukang-fix-148344-incorrect-prec…
jhpratt Nov 7, 2025
694ddb3
Rollup merge of #148570 - TomFryersMidsummer:dir-locals, r=chenyukang
jhpratt Nov 7, 2025
dff3697
Rollup merge of #148575 - vyacheslavhere:fix-query-system-readme-link…
jhpratt Nov 7, 2025
9d00190
Rollup merge of #148578 - WaffleLapkin:equal-alignment-atomic-from-mu…
jhpratt Nov 7, 2025
0dafd50
Rollup merge of #148603 - pietroalbini:ea-1.91.1-relnotes, r=pietroal…
jhpratt Nov 7, 2025
c932d7c
Rollup merge of #148609 - AMDmi3:rsplit_once_example, r=chenyukang
jhpratt Nov 7, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Version 1.91.1 (2025-11-10)
===========================

<a id="1.91.1"></a>

- [Enable file locking support in illumos](https://github.com/rust-lang/rust/pull/148322). This fixes Cargo not locking the build directory on illumos.
- [Fix `wasm_import_module` attribute cross-crate](https://github.com/rust-lang/rust/pull/148363). This fixes linker errors on WASM targets.

Version 1.91.0 (2025-10-30)
==========================

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ builtin_macros_duplicate_macro_attribute = duplicated attribute
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
.cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}`
.custom = use `std::env::var({$var_expr})` to read the variable at run time
builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string
Expand Down
53 changes: 53 additions & 0 deletions compiler/rustc_builtin_macros/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_ast::token::{self, LitKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{ExprKind, GenericArg, Mutability};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::edit_distance::edit_distance;
use rustc_span::{Ident, Span, Symbol, kw, sym};
use thin_vec::thin_vec;

Expand Down Expand Up @@ -144,6 +145,12 @@ pub(crate) fn expand_env<'cx>(
if let Some(msg_from_user) = custom_msg {
cx.dcx()
.emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user })
} else if let Some(suggested_var) = find_similar_cargo_var(var.as_str()) {
cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVarTypo {
span,
var: *symbol,
suggested_var: Symbol::intern(suggested_var),
})
} else if is_cargo_env_var(var.as_str()) {
cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar {
span,
Expand Down Expand Up @@ -176,3 +183,49 @@ fn is_cargo_env_var(var: &str) -> bool {
|| var.starts_with("DEP_")
|| matches!(var, "OUT_DIR" | "OPT_LEVEL" | "PROFILE" | "HOST" | "TARGET")
}

const KNOWN_CARGO_VARS: &[&str] = &[
// List of known Cargo environment variables that are set for crates (not build scripts, OUT_DIR etc).
// See: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
"CARGO_PKG_VERSION",
"CARGO_PKG_VERSION_MAJOR",
"CARGO_PKG_VERSION_MINOR",
"CARGO_PKG_VERSION_PATCH",
"CARGO_PKG_VERSION_PRE",
"CARGO_PKG_AUTHORS",
"CARGO_PKG_NAME",
"CARGO_PKG_DESCRIPTION",
"CARGO_PKG_HOMEPAGE",
"CARGO_PKG_REPOSITORY",
"CARGO_PKG_LICENSE",
"CARGO_PKG_LICENSE_FILE",
"CARGO_PKG_RUST_VERSION",
"CARGO_PKG_README",
"CARGO_MANIFEST_DIR",
"CARGO_MANIFEST_PATH",
"CARGO_CRATE_NAME",
"CARGO_BIN_NAME",
"CARGO_PRIMARY_PACKAGE",
];

fn find_similar_cargo_var(var: &str) -> Option<&'static str> {
if !var.starts_with("CARGO_") {
return None;
}

let lookup_len = var.chars().count();
let max_dist = std::cmp::max(lookup_len, 3) / 3;
let mut best_match = None;
let mut best_distance = usize::MAX;

for &known_var in KNOWN_CARGO_VARS {
if let Some(distance) = edit_distance(var, known_var, max_dist) {
if distance < best_distance {
best_distance = distance;
best_match = Some(known_var);
}
}
}

best_match
}
8 changes: 8 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,14 @@ pub(crate) enum EnvNotDefined<'a> {
var_expr: &'a rustc_ast::Expr,
},
#[diag(builtin_macros_env_not_defined)]
#[help(builtin_macros_cargo_typo)]
CargoEnvVarTypo {
#[primary_span]
span: Span,
var: Symbol,
suggested_var: Symbol,
},
#[diag(builtin_macros_env_not_defined)]
#[help(builtin_macros_custom)]
CustomEnvVar {
#[primary_span]
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,8 @@ pub(crate) fn run_pass_manager(
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage);
}

if enable_gpu && !thin {
// Here we only handle the GPU host (=cpu) code.
if enable_gpu && !thin && !cgcx.target_is_like_gpu {
let cx =
SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size);
crate::builder::gpu_offload::handle_gpu_code(cgcx, &cx);
Expand Down
70 changes: 69 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use crate::errors::{
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
use crate::llvm::{self, DiagnosticInfo};
use crate::type_::llvm_type_ptr;
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
use crate::{LlvmCodegenBackend, ModuleLlvm, SimpleCx, base, common, llvm_util};

pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> ! {
match llvm::last_error() {
Expand Down Expand Up @@ -645,6 +645,74 @@ pub(crate) unsafe fn llvm_optimize(
None
};

fn handle_offload<'ll>(cx: &'ll SimpleCx<'_>, old_fn: &llvm::Value) {
let old_fn_ty = cx.get_type_of_global(old_fn);
let old_param_types = cx.func_params_types(old_fn_ty);
let old_param_count = old_param_types.len();
if old_param_count == 0 {
return;
}

let first_param = llvm::get_param(old_fn, 0);
let c_name = llvm::get_value_name(first_param);
let first_arg_name = str::from_utf8(&c_name).unwrap();
// We might call llvm_optimize (and thus this code) multiple times on the same IR,
// but we shouldn't add this helper ptr multiple times.
// FIXME(offload): This could break if the user calls his first argument `dyn_ptr`.
if first_arg_name == "dyn_ptr" {
return;
}

// Create the new parameter list, with ptr as the first argument
let mut new_param_types = Vec::with_capacity(old_param_count as usize + 1);
new_param_types.push(cx.type_ptr());
new_param_types.extend(old_param_types);

// Create the new function type
let ret_ty = unsafe { llvm::LLVMGetReturnType(old_fn_ty) };
let new_fn_ty = cx.type_func(&new_param_types, ret_ty);

// Create the new function, with a temporary .offload name to avoid a name collision.
let old_fn_name = String::from_utf8(llvm::get_value_name(old_fn)).unwrap();
let new_fn_name = format!("{}.offload", &old_fn_name);
let new_fn = cx.add_func(&new_fn_name, new_fn_ty);
let a0 = llvm::get_param(new_fn, 0);
llvm::set_value_name(a0, CString::new("dyn_ptr").unwrap().as_bytes());

// Here we map the old arguments to the new arguments, with an offset of 1 to make sure
// that we don't use the newly added `%dyn_ptr`.
unsafe {
llvm::LLVMRustOffloadMapper(cx.llmod(), old_fn, new_fn);
}

llvm::set_linkage(new_fn, llvm::get_linkage(old_fn));
llvm::set_visibility(new_fn, llvm::get_visibility(old_fn));

// Replace all uses of old_fn with new_fn (RAUW)
unsafe {
llvm::LLVMReplaceAllUsesWith(old_fn, new_fn);
}
let name = llvm::get_value_name(old_fn);
unsafe {
llvm::LLVMDeleteFunction(old_fn);
}
// Now we can re-use the old name, without name collision.
llvm::set_value_name(new_fn, &name);
}

if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) {
let cx =
SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size);
// For now we only support up to 10 kernels named kernel_0 ... kernel_9, a follow-up PR is
// introducing a proper offload intrinsic to solve this limitation.
for num in 0..9 {
let name = format!("kernel_{num}");
if let Some(kernel) = cx.get_function(&name) {
handle_offload(&cx, kernel);
}
}
}

let mut llvm_profiler = cgcx
.prof
.llvm_recording_enabled()
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub(crate) fn handle_gpu_code<'ll>(
let mut memtransfer_types = vec![];
let mut region_ids = vec![];
let offload_entry_ty = TgtOffloadEntry::new_decl(&cx);
// This is a temporary hack, we only search for kernel_0 to kernel_9 functions.
// There is a draft PR in progress which will introduce a proper offload intrinsic to remove
// this limitation.
for num in 0..9 {
let kernel = cx.get_function(&format!("kernel_{num}"));
if let Some(kernel) = kernel {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,11 @@ unsafe extern "C" {

// Operations on functions
pub(crate) fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint);
pub(crate) fn LLVMAddFunction<'a>(
Mod: &'a Module,
Name: *const c_char,
FunctionTy: &'a Type,
) -> &'a Value;
pub(crate) fn LLVMDeleteFunction(Fn: &Value);

// Operations about llvm intrinsics
Expand Down Expand Up @@ -2017,6 +2022,7 @@ unsafe extern "C" {
) -> &Attribute;

// Operations on functions
pub(crate) fn LLVMRustOffloadMapper<'a>(M: &'a Module, Fn: &'a Value, Fn: &'a Value);
pub(crate) fn LLVMRustGetOrInsertFunction<'a>(
M: &'a Module,
Name: *const c_char,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_llvm/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
unsafe { llvm::LLVMVectorType(ty, len as c_uint) }
}

pub(crate) fn add_func(&self, name: &str, ty: &'ll Type) -> &'ll Value {
let name = SmallCStr::new(name);
unsafe { llvm::LLVMAddFunction(self.llmod(), name.as_ptr(), ty) }
}

pub(crate) fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> {
unsafe {
let n_args = llvm::LLVMCountParamTypes(ty) as usize;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
pub target_arch: String,
pub target_is_like_darwin: bool,
pub target_is_like_aix: bool,
pub target_is_like_gpu: bool,
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
pub pointer_size: Size,
Expand Down Expand Up @@ -1309,6 +1310,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
target_arch: tcx.sess.target.arch.to_string(),
target_is_like_darwin: tcx.sess.target.is_like_darwin,
target_is_like_aix: tcx.sess.target.is_like_aix,
target_is_like_gpu: tcx.sess.target.is_like_gpu,
split_debuginfo: tcx.sess.split_debuginfo(),
split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind,
parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
false
};

// Special case: range expressions are desugared to struct literals in HIR,
// so they would normally return `Unambiguous` precedence in expr.precedence.
// we should return `Range` precedence for correct parenthesization in suggestions.
if is_range_literal(expr) {
return ExprPrecedence::Range;
}

expr.precedence(&has_attr)
}

Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "llvm/Support/Signals.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <iostream>

// for raw `write` in the bad-alloc handler
Expand Down Expand Up @@ -142,6 +144,28 @@ extern "C" void LLVMRustPrintStatistics(RustStringRef OutBuf) {
llvm::PrintStatistics(OS);
}

extern "C" void LLVMRustOffloadMapper(LLVMModuleRef M, LLVMValueRef OldFn,
LLVMValueRef NewFn) {
llvm::Module *module = llvm::unwrap(M);
llvm::Function *oldFn = llvm::unwrap<llvm::Function>(OldFn);
llvm::Function *newFn = llvm::unwrap<llvm::Function>(NewFn);

// Map old arguments to new arguments. We skip the first dyn_ptr argument,
// since it can't be used directly by user code.
llvm::ValueToValueMapTy vmap;
auto newArgIt = newFn->arg_begin();
newArgIt->setName("dyn_ptr");
++newArgIt; // skip %dyn_ptr
for (auto &oldArg : oldFn->args()) {
vmap[&oldArg] = &*newArgIt++;
}

llvm::SmallVector<llvm::ReturnInst *, 8> returns;
llvm::CloneFunctionInto(newFn, oldFn, vmap,
llvm::CloneFunctionChangeType::LocalChangesOnly,
returns);
}

extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
size_t NameLen) {
return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_query_system/src/dep_graph/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
To learn more about how dependency tracking works in rustc, see the [rustc
guide].
To learn more about how dependency tracking works in rustc, see the [rustc dev guide].

[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html
1 change: 1 addition & 0 deletions compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ impl RiscvInterruptKind {
///
/// The signature represented by this type may not match the MIR function signature.
/// Certain attributes, like `#[track_caller]` can introduce additional arguments, which are present in [`FnAbi`], but not in `FnSig`.
/// The std::offload module also adds an addition dyn_ptr argument to the GpuKernel ABI.
/// While this difference is rarely relevant, it should still be kept in mind.
///
/// I will do my best to describe this structure, but these
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ impl Target {
forward!(is_like_darwin);
forward!(is_like_solaris);
forward!(is_like_windows);
forward!(is_like_gpu);
forward!(is_like_msvc);
forward!(is_like_wasm);
forward!(is_like_android);
Expand Down Expand Up @@ -342,6 +343,7 @@ impl ToJson for Target {
target_option_val!(is_like_darwin);
target_option_val!(is_like_solaris);
target_option_val!(is_like_windows);
target_option_val!(is_like_gpu);
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(is_like_android);
Expand Down Expand Up @@ -562,6 +564,7 @@ struct TargetSpecJson {
is_like_darwin: Option<bool>,
is_like_solaris: Option<bool>,
is_like_windows: Option<bool>,
is_like_gpu: Option<bool>,
is_like_msvc: Option<bool>,
is_like_wasm: Option<bool>,
is_like_android: Option<bool>,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2180,6 +2180,8 @@ pub struct TargetOptions {
/// Also indicates whether to use Apple-specific ABI changes, such as extending function
/// parameters to 32-bits.
pub is_like_darwin: bool,
/// Whether the target is a GPU (e.g. NVIDIA, AMD, Intel).
pub is_like_gpu: bool,
/// Whether the target toolchain is like Solaris's.
/// Only useful for compiling against Illumos/Solaris,
/// as they have a different set of linker flags. Defaults to false.
Expand Down Expand Up @@ -2590,6 +2592,7 @@ impl Default for TargetOptions {
abi_return_struct_as_int: false,
is_like_aix: false,
is_like_darwin: false,
is_like_gpu: false,
is_like_solaris: false,
is_like_windows: false,
is_like_msvc: false,
Expand Down Expand Up @@ -2756,6 +2759,11 @@ impl Target {
self.os == "solaris" || self.os == "illumos",
"`is_like_solaris` must be set if and only if `os` is `solaris` or `illumos`"
);
check_eq!(
self.is_like_gpu,
self.arch == Arch::Nvptx64 || self.arch == Arch::AmdGpu,
"`is_like_gpu` must be set if and only if `target` is `nvptx64` or `amdgcn`"
);
check_eq!(
self.is_like_windows,
self.os == "windows" || self.os == "uefi" || self.os == "cygwin",
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub(crate) fn target() -> Target {
no_builtins: true,
simd_types_indirect: false,

// Clearly a GPU
is_like_gpu: true,

// Allow `cdylib` crate type.
dynamic_linking: true,
only_cdylib: true,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub(crate) fn target() -> Target {
// Let the `ptx-linker` to handle LLVM lowering into MC / assembly.
obj_is_bitcode: true,

// Clearly a GPU
is_like_gpu: true,

// Convenient and predicable naming scheme.
dll_prefix: "".into(),
dll_suffix: ".ptx".into(),
Expand Down
Loading
Loading