Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
aee14eb
declare C and C-unwind as mutually ABI-compatible
RalfJung Aug 28, 2026
3a4c1c0
Add Tier 3 targets for Hyperlight guests
syntactically Sep 21, 2026
a8210e1
rustdoc: Fix where-clause placement of free const items
fmease Sep 24, 2026
9f3299e
rustdoc: Fix where-clause placement of checked type aliases
fmease Sep 24, 2026
2160998
Refactor CodeGen Pipeline Setup into a Single Function
boomanaiden154 Sep 9, 2026
dc7db04
feedback
boomanaiden154 Sep 24, 2026
5f463ae
more lifetime fixes
boomanaiden154 Sep 24, 2026
237cfc3
remove unnecessary panic
WaffleLapkin Jul 22, 2026
d5a81cb
ignore hanging next-solver tests, remove unnecessary ignore test
lcnr Oct 1, 2026
b923d1e
ctfe: Constify the `abort` intrinsic
tgross35 Oct 1, 2026
767210f
core: Unstably constify `abort_immediate`
tgross35 Oct 1, 2026
1416718
Add tests for `()`, `!`, and `bool`'s size and alignment to `coretests`.
zachs18 Sep 30, 2026
bc54083
Rollup merge of #162556 - boomanaiden154:rustc-legacy-pm-refactoring-…
jhpratt Oct 2, 2026
265a77c
Rollup merge of #163254 - fmease:rustdoc-fix-where-clause-placement, …
jhpratt Oct 2, 2026
d080065
Rollup merge of #163621 - tgross35:const-abort-immediate, r=RalfJung,…
jhpratt Oct 2, 2026
e0a574e
Rollup merge of #161904 - RalfJung:unwind-abi-compat, r=Mark-Simulacrum
jhpratt Oct 2, 2026
e0b86b7
Rollup merge of #163144 - syntactically:hyperlight-targets, r=wesleyw…
jhpratt Oct 2, 2026
f7314d2
Rollup merge of #163537 - WaffleLapkin:nopanic, r=RalfJung
jhpratt Oct 2, 2026
37062d7
Rollup merge of #163570 - zachs18:never-bool-size-align-test, r=tgross35
jhpratt Oct 2, 2026
398c579
Rollup merge of #163606 - lcnr:ui-test-suite-cleanup, r=lqd
jhpratt Oct 2, 2026
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
5 changes: 1 addition & 4 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,14 @@ fn write_output_file<'ll>(
std::ptr::null()
};
let result = unsafe {
let pm = llvm::LLVMCreatePassManager();
llvm::LLVMAddAnalysisPasses(target, pm);
llvm::LLVMRustAddLibraryInfo(target, pm, m, no_builtins);
llvm::LLVMRustWriteOutputFile(
target,
pm,
m,
output_c.as_ptr(),
dwo_output_ptr,
file_type,
verify_llvm_ir,
no_builtins,
)
};

Expand Down
15 changes: 1 addition & 14 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,6 @@ unsafe extern "C" {
}
#[repr(C)]
pub(crate) struct Builder<'a>(InvariantOpaque<'a>);
#[repr(C)]
pub(crate) struct PassManager<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type TargetMachine;
}
Expand Down Expand Up @@ -1637,11 +1635,6 @@ unsafe extern "C" {
/// Writes a module to the specified path. Returns 0 on success.
pub(crate) fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;

/// Creates a legacy pass manager -- only used for final codegen.
pub(crate) fn LLVMCreatePassManager<'a>() -> &'a mut PassManager<'a>;

pub(crate) fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);

pub(crate) fn LLVMGetHostCPUFeatures() -> *mut c_char;

pub(crate) fn LLVMDisposeMessage(message: *mut c_char);
Expand Down Expand Up @@ -2430,20 +2423,14 @@ unsafe extern "C" {

pub(crate) fn LLVMRustDisposeMCSubtargetInfo(MCInfo: ptr::NonNull<MCSubtargetInfo>);

pub(crate) fn LLVMRustAddLibraryInfo<'a>(
T: &TargetMachine,
PM: &PassManager<'a>,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub(crate) fn LLVMRustWriteOutputFile<'a>(
T: &'a TargetMachine,
PM: *mut PassManager<'a>,
M: &'a Module,
Output: *const c_char,
DwoOutput: *const c_char,
FileType: FileType,
VerifyIR: bool,
DisableSimplifyLibCalls: bool,
) -> LLVMRustResult;
pub(crate) fn LLVMRustOptimize<'a>(
M: &'a Module,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub enum ConstEvalErrKind {
col: u32,
file: Symbol,
},
Abort,
WriteThroughImmutablePointer,
/// Called `const_make_global` twice.
ConstMakeGlobalPtrAlreadyMadeGlobal(AllocId),
Expand All @@ -51,6 +52,7 @@ impl fmt::Display for ConstEvalErrKind {
write!(f, "modifying a static's initial value from another static's initializer")
}
Panic { msg, .. } => write!(f, "evaluation panicked: {msg}"),
Abort => write!(f, "the program aborted execution"),
RecursiveStatic => {
write!(f, "encountered static that tried to access itself during initialization")
}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{CRATE_HIR_ID, HirId};
use rustc_lint_defs::builtin::LONG_RUNNING_CONST_EVAL;
use rustc_middle::mir;
use rustc_middle::mir::AssertMessage;
use rustc_middle::mir::interpret::ReportedErrorInfo;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::consts::ConstExt;
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout, ValidityRequirement};
use rustc_middle::ty::{self, FieldInfo, ScalarInt, Ty, TyCtxt};
use rustc_middle::{mir, throw_machine_stop};
use rustc_span::{Span, Symbol, bug, span_bug, sym};
use rustc_target::callconv::FnAbi;
use tracing::debug;
Expand Down Expand Up @@ -484,6 +484,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {

// CTFE-specific intrinsics.
match intrinsic_name {
sym::abort => {
// Note that `abort` is also hooked separately in Miri.
throw_machine_stop!(ConstEvalErrKind::Abort);
}
sym::ptr_guaranteed_cmp => {
let a = ecx.read_scalar(&args[0])?;
let b = ecx.read_scalar(&args[1])?;
Expand Down
65 changes: 33 additions & 32 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,30 +447,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
return wrap(TM);
}

// Unfortunately, the LLVM C API doesn't provide a way to create the
// TargetLibraryInfo pass, so we use this method to do so.
extern "C" void LLVMRustAddLibraryInfo(LLVMTargetMachineRef T,
LLVMPassManagerRef PMR, LLVMModuleRef M,
bool DisableSimplifyLibCalls) {
auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
TargetOptions *Options = &unwrap(T)->Options;
auto TLII = TargetLibraryInfoImpl(TargetTriple);
if (DisableSimplifyLibCalls)
TLII.disableAllFunctions();
unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
#if LLVM_VERSION_GE(24, 0)
// LLVM 24 removed TargetOptions::EABIVersion and ExceptionModel; the EABI
// version and exception model are now derived from the target triple and
// module flags respectively instead.
unwrap(PMR)->add(new RuntimeLibraryInfoWrapper(Options->MCOptions.ABIName,
Options->VecLib));
#elif LLVM_VERSION_GE(22, 0)
unwrap(PMR)->add(new RuntimeLibraryInfoWrapper(
TargetTriple, Options->ExceptionModel, Options->FloatABIType,
Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib));
#endif
}

extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
// Initializing the command-line options more than once is not allowed. So,
// check if they've already been initialized. (This could happen if we're
Expand Down Expand Up @@ -500,10 +476,34 @@ static CodeGenFileType fromRust(LLVMRustFileType Type) {
}

extern "C" LLVMRustResult
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
LLVMModuleRef M, const char *Path, const char *DwoPath,
LLVMRustFileType RustFileType, bool VerifyIR) {
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMModuleRef M,
const char *Path, const char *DwoPath,
LLVMRustFileType RustFileType, bool VerifyIR,
bool DisableSimplifyLibCalls) {
std::unique_ptr<llvm::legacy::PassManager> PM =
std::make_unique<llvm::legacy::PassManager>();

PM->add(createTargetTransformInfoWrapperPass(
unwrap(Target)->getTargetIRAnalysis()));

auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
TargetOptions *Options = &unwrap(Target)->Options;
auto TLII = TargetLibraryInfoImpl(TargetTriple);
if (DisableSimplifyLibCalls)
TLII.disableAllFunctions();
PM->add(new TargetLibraryInfoWrapperPass(TLII));
#if LLVM_VERSION_GE(24, 0)
// LLVM 24 removed TargetOptions::EABIVersion and ExceptionModel; the EABI
// version and exception model are now derived from the target triple and
// module flags respectively instead.
PM->add(new RuntimeLibraryInfoWrapper(Options->MCOptions.ABIName,
Options->VecLib));
#elif LLVM_VERSION_GE(22, 0)
PM->add(new RuntimeLibraryInfoWrapper(
TargetTriple, Options->ExceptionModel, Options->FloatABIType,
Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib));
#endif

auto FileType = fromRust(RustFileType);

std::string ErrorInfo;
Expand All @@ -516,6 +516,9 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
return LLVMRustResult::Failure;
}

// TargetMachine::addPassesToEmitFile stores pointers to the output streams
// in a couple of places inside of the object. Explicitly delete the PM after
// we call run() to avoid dangling references.
auto BOS = buffer_ostream(OS);
if (DwoPath) {
auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None);
Expand All @@ -529,15 +532,13 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
auto DBOS = buffer_ostream(DOS);
unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, !VerifyIR);
PM->run(*unwrap(M));
PM.reset();
} else {
unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, !VerifyIR);
PM->run(*unwrap(M));
PM.reset();
}

// Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
// stream (OS), so the only real safe place to delete this is here? Don't we
// wish this was written in Rust?
LLVMDisposePassManager(PMR);
return LLVMRustResult::Success;
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2227,8 +2227,8 @@ rustc_queries! {
}

/// Do not call this query directly: invoke `Ty::is_opsem_inhabited` instead.
query is_opsem_inhabited_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is inhabited on the opsem level", env.value }
query is_opsem_inhabited_adt_cached(env: ty::PseudoCanonicalInput<'tcx, (ty::AdtDef<'tcx>, ty::GenericArgsRef<'tcx>)>) -> bool {
desc { "computing whether `{:?}` is inhabited on the opsem level", env.value }
}

query crate_dep_kind(_: CrateNum) -> CrateDepKind {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/query/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
}
}

impl<'tcx> QueryKey for (ty::AdtDef<'tcx>, ty::GenericArgsRef<'tcx>) {
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
tcx.def_span(self.0.did())
}
}

impl QueryKey for Symbol {
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
DUMMY_SP
Expand Down
34 changes: 14 additions & 20 deletions compiler/rustc_middle/src/ty/inhabitedness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
//! This code should only compile in modules where the uninhabitedness of `Foo`
//! is visible.

use std::assert_matches;

use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind;
use rustc_span::bug;
Expand All @@ -65,7 +63,7 @@ pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
inhabited_predicate_for_def,
inhabited_predicate_type,
is_opsem_inhabited_raw,
is_opsem_inhabited_adt_cached,
..*providers
};
}
Expand Down Expand Up @@ -271,7 +269,7 @@ struct OpsemInhabitedCtx<'tcx> {
tcx: TyCtxt<'tcx>,
typing_env: TypingEnv<'tcx>,
/// IDs of ADTs that have been encountered in the current stack.
/// It's `None` unless we are inside the `is_opsem_inhabited_raw` query,
/// It's `None` unless we are inside the `is_opsem_inhabited_adt_cached` query,
/// which is only invoked for more complex types.
seen: Option<FxHashSet<DefId>>,
/// If an ADT is encountered recursively within itself, then `stop_at_ref`
Expand Down Expand Up @@ -330,7 +328,7 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> {
let base = tcx.instantiate_bound_regions_with_erased((*base).into());
self.is_inhabited_ty(base)
}
ty::Adt(..) => self.is_inhabited_adt_ty(ty),
ty::Adt(def, args) => self.is_inhabited_adt_ty(def, args),

ty::Error(_error_guaranteed) => {
// We have a token proving there was an error, so we can return a dummy value.
Expand All @@ -348,10 +346,11 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> {
}
}

fn is_inhabited_adt_ty(&mut self, ty: Ty<'tcx>) -> bool {
let ty::Adt(adt_def, adt_args) = *ty.kind() else {
unreachable! {}
};
fn is_inhabited_adt_ty(
&mut self,
adt_def: ty::AdtDef<'tcx>,
adt_args: ty::GenericArgsRef<'tcx>,
) -> bool {
let Self { tcx, typing_env, .. } = *self;

if adt_def.is_union() {
Expand All @@ -361,7 +360,8 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> {

let Some(seen) = self.seen.as_mut() else {
// stop recursing, invoke the query.
return tcx.is_opsem_inhabited_raw(typing_env.as_query_input(ty));
return tcx
.is_opsem_inhabited_adt_cached(typing_env.as_query_input((adt_def, adt_args)));
};

let new_adt = seen.insert(adt_def.did());
Expand Down Expand Up @@ -391,17 +391,11 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> {
}
}

fn is_opsem_inhabited_raw<'tcx>(
fn is_opsem_inhabited_adt_cached<'tcx>(
tcx: TyCtxt<'tcx>,
env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
env: ty::PseudoCanonicalInput<'tcx, (ty::AdtDef<'tcx>, ty::GenericArgsRef<'tcx>)>,
) -> bool {
let (ty, typing_env) = (env.value, env.typing_env);
assert_matches!(
ty.kind(),
ty::Adt(..),
"the query should only be invoked by `Ty::is_opsem_inhabited`"
);

let ((def, args), typing_env) = (env.value, env.typing_env);
OpsemInhabitedCtx { tcx, typing_env, seen: Some(FxHashSet::default()), stop_at_ref: false }
.is_inhabited_adt_ty(ty)
.is_inhabited_adt_ty(def, args)
}
19 changes: 19 additions & 0 deletions compiler/rustc_target/src/spec/base/hyperlight.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::spec::{
Cc, CodeModel, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, StackProbeType, TargetOptions,
};

pub(crate) fn opts() -> TargetOptions {
TargetOptions {
os: Os::Hyperlight,
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
disable_redzone: true,
panic_strategy: PanicStrategy::Abort,
stack_probes: StackProbeType::Inline,
code_model: Some(CodeModel::Small),
relocation_model: RelocModel::Pic,
position_independent_executables: true,
static_position_independent_executables: true,
..Default::default()
}
}
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub(crate) mod helenos;
pub(crate) mod hermit;
pub(crate) mod hurd;
pub(crate) mod hurd_gnu;
pub(crate) mod hyperlight;
pub(crate) mod illumos;
pub(crate) mod l4re;
pub(crate) mod linux;
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,9 @@ supported_targets! {
("i686-oe-linux-gnu", i686_oe_linux_gnu),
("riscv64-oe-linux-gnu", riscv64_oe_linux_gnu),
("x86_64-oe-linux-gnu", x86_64_oe_linux_gnu),

("aarch64-unknown-hyperlight", aarch64_unknown_hyperlight),
("x86_64-unknown-hyperlight", x86_64_unknown_hyperlight),
}

/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
Expand Down Expand Up @@ -1857,6 +1860,7 @@ crate::target_spec_enum! {
Hermit = "hermit",
Horizon = "horizon",
Hurd = "hurd",
Hyperlight = "hyperlight",
Illumos = "illumos",
IOs = "ios",
L4Re = "l4re",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Hyperlight Guest target for AArch64

use crate::spec::{Arch, SanitizerSet, Target, TargetMetadata, TargetOptions, base};

pub(crate) fn target() -> Target {
let opts = TargetOptions {
features: "+v8.1a,+strict-align,+neon,+fp-armv8".into(),
direct_access_external_data: Some(true),

supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
max_atomic_width: Some(128),
default_uwtable: true,
supports_xray: true,
..base::hyperlight::opts()
};
Target {
llvm_target: "aarch64-unknown-none".into(),
metadata: TargetMetadata {
description: Some("ARM64 Hyperlight guest".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 64,
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: Arch::AArch64,
options: opts,
}
}
Loading
Loading