Skip to content

Rollup of 9 pull requests #136030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 62 commits into from
Jan 25, 2025
Merged
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
98d7162
Preparing for merge from rustc
Kobzol Jan 5, 2025
25beca9
add josh-sync build dir to gitignore (#2196)
BoxyUwU Jan 5, 2025
be5d781
Add rustc-dev-guide to the list of repositories managed by josh (#2197)
Kobzol Jan 6, 2025
8561cc8
Only keep label description in Forge docs
jieyouxu Jan 5, 2025
d91316e
Fix broken raw HTML (#2198)
max-heller Jan 7, 2025
a5e424e
Preparing for merge from rustc
Kobzol Jan 8, 2025
2f3ee5d
Merge from rustc
Kobzol Jan 8, 2025
5a11197
Merge pull request #2200 from Kobzol/rustc-pull
Kobzol Jan 8, 2025
9577119
Save linkcheck cache always
marxin Jan 6, 2025
1ffe0ea
Update key
marxin Jan 8, 2025
7e2a690
Print an explicit message if the base repo head commit is up-to-date
Kobzol Jan 8, 2025
f761e1a
Error if there is nothing to pull
Kobzol Jan 8, 2025
42c284e
Merge pull request #2030 from marxin/ci-cache
camelid Jan 9, 2025
b4297e7
ci: Remove incorrect use of `continue-on-error`
camelid Jan 9, 2025
ce0d5c1
Merge pull request #2203 from camelid/ci-fix
Kobzol Jan 9, 2025
fcbcc74
Document how to find the configuration used in CI
ehuss Jan 10, 2025
43848be
Fix calculate-job-matrix.py link
ehuss Jan 10, 2025
f53bce4
Merge pull request #2206 from ehuss/fix-matrix-link
jieyouxu Jan 10, 2025
90e0127
Merge pull request #2205 from ehuss/ci-config
jieyouxu Jan 10, 2025
980412f
Add CI workflow for performing rustc-pull
Kobzol Jan 8, 2025
31f855b
Fix some broken links
camelid Jan 15, 2025
284d05d
Merge pull request #2208 from camelid/fix-some-links
jieyouxu Jan 15, 2025
1327eeb
Merge pull request #2202 from Kobzol/pull-ci
jieyouxu Jan 15, 2025
4a03a9f
fix some more typos
rmehri01 Jan 15, 2025
1df83a7
Merge pull request #2209 from rmehri01/typos
jieyouxu Jan 15, 2025
f8f912d
nyaa
lcnr Jan 15, 2025
3423f1e
Merge pull request #2210 from lcnr/promote-type-tests
lcnr Jan 15, 2025
6a57fbf
compiletest: fix outdated `rustdoc-js` test suite name
jieyouxu Jan 17, 2025
b38aa65
Merge pull request #2212 from jieyouxu/fix-rustdoc-js
jieyouxu Jan 17, 2025
80c664a
remove outdated text about wfx implies
patrickoliveira15 Jan 17, 2025
84fdb51
Merge pull request #2211 from patrickoliveira15/patch/inference-invar…
JohnTitor Jan 17, 2025
01d1aef
document order of items in iterator from drain
hkBst Jan 19, 2025
c282ac8
Fix whitespace
hkBst Jan 19, 2025
d6b0828
docs: document how to install a suitable `josh-proxy` locally
jieyouxu Jan 18, 2025
24f264a
Merge pull request #2213 from jieyouxu/install-josh-proxy
jieyouxu Jan 20, 2025
29be13d
Add portable SIMD to list of subtrees
Kobzol Jan 20, 2025
808bd95
Preparing for merge from rustc
Kobzol Jan 20, 2025
1e0204b
Merge from rustc
Kobzol Jan 20, 2025
1b5b051
Merge pull request #2214 from Kobzol/subtree-portable-simd
jieyouxu Jan 20, 2025
470ab13
Merge pull request #2215 from Kobzol/pull
Kobzol Jan 20, 2025
28b5e11
Send a message to Zulip when a sync finishes
Kobzol Jan 20, 2025
a3f061c
Merge pull request #2216 from Kobzol/ci-pull-zulip
Kobzol Jan 20, 2025
f416648
Add memory layout documentation to generic NonZero<T>
carlsverre Jan 23, 2025
32cf7cc
Use short type string in E0308 secondary span label
estebank Jan 23, 2025
af2ce8b
don't drop types with no drop glue when tailcalling
WaffleLapkin Jan 24, 2025
530f8bb
Fix indent of trait items on mobile
GuillaumeGomez Jan 24, 2025
caacb04
Add GUI regression test for indent of trait items on mobile
GuillaumeGomez Jan 24, 2025
97e07da
Do not assume const params are printed after type params
compiler-errors Jan 19, 2025
ab27463
Add `File already exists` error doc to `hard_link` function
Harshit933 Jan 12, 2025
4a8de9a
Update library/core/src/num/nonzero.rs
carlsverre Jan 24, 2025
83339bf
add a regression test
WaffleLapkin Jan 24, 2025
9b82f20
bless miri test
WaffleLapkin Jan 24, 2025
386c233
Make CodegenCx and Builder generic
ZuseZ4 Jan 24, 2025
0741cc0
Rollup merge of #135415 - Harshit933:hard-link-error, r=ChrisDenton
matthiaskrgr Jan 24, 2025
1e454fe
Rollup merge of #135581 - EnzymeAD:refactor-codgencx, r=oli-obk
matthiaskrgr Jan 24, 2025
5750815
Rollup merge of #135728 - hkBst:patch-8, r=joboet
matthiaskrgr Jan 24, 2025
ca5fa66
Rollup merge of #135749 - compiler-errors:param-ordering, r=davidtwco
matthiaskrgr Jan 24, 2025
dcd43d3
Rollup merge of #135829 - Kobzol:rustc-push, r=jieyouxu
matthiaskrgr Jan 24, 2025
884ec6b
Rollup merge of #135938 - carlsverre:master, r=joboet
matthiaskrgr Jan 24, 2025
8824ae6
Rollup merge of #135949 - estebank:shorten-ty, r=davidtwco
matthiaskrgr Jan 24, 2025
99e34a4
Rollup merge of #135976 - WaffleLapkin:tailcall-nodrop, r=oli-obk
matthiaskrgr Jan 24, 2025
d15cf36
Rollup merge of #135998 - GuillaumeGomez:fix-trait-items-mobile-inden…
matthiaskrgr Jan 24, 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: 0 additions & 1 deletion compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -444,7 +444,6 @@ impl WriteBackendMethods for GccCodegenBackend {
}
fn autodiff(
_cgcx: &CodegenContext<Self>,
_tcx: TyCtxt<'_>,
_module: &ModuleCodegen<Self::Module>,
_diff_fncs: Vec<AutoDiffItem>,
_config: &ModuleConfig,
150 changes: 138 additions & 12 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::borrow::Cow;
use std::borrow::{Borrow, Cow};
use std::ops::Deref;
use std::{iter, ptr};

@@ -31,27 +31,135 @@ use tracing::{debug, instrument};
use crate::abi::FnAbiLlvmExt;
use crate::attributes;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::context::{CodegenCx, SimpleCx};
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;

// All Builders must have an llfn associated with them
#[must_use]
pub(crate) struct Builder<'a, 'll, 'tcx> {
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SimpleCx<'ll>>> {
pub llbuilder: &'ll mut llvm::Builder<'ll>,
pub cx: &'a CodegenCx<'ll, 'tcx>,
pub cx: &'a CX,
}

impl Drop for Builder<'_, '_, '_> {
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>;

impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
fn drop(&mut self) {
unsafe {
llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
}
}
}

impl<'a, 'll> SBuilder<'a, 'll> {
fn call(
&mut self,
llty: &'ll Type,
llfn: &'ll Value,
args: &[&'ll Value],
funclet: Option<&Funclet<'ll>>,
) -> &'ll Value {
debug!("call {:?} with args ({:?})", llfn, args);

let args = self.check_call("call", llty, llfn, args);
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
if let Some(funclet_bundle) = funclet_bundle {
bundles.push(funclet_bundle);
}

let call = unsafe {
llvm::LLVMBuildCallWithOperandBundles(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
bundles.as_ptr(),
bundles.len() as c_uint,
c"".as_ptr(),
)
};
call
}

fn with_scx(scx: &'a SimpleCx<'ll>) -> Self {
// Create a fresh builder from the simple context.
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) };
SBuilder { llbuilder, cx: scx }
}
}
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
}

fn ret_void(&mut self) {
unsafe {
llvm::LLVMBuildRetVoid(self.llbuilder);
}
}

fn ret(&mut self, v: &'ll Value) {
unsafe {
llvm::LLVMBuildRet(self.llbuilder, v);
}
}
}
impl<'a, 'll> SBuilder<'a, 'll> {
fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> {
let bx = SBuilder::with_scx(cx);
unsafe {
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
}
bx
}

fn check_call<'b>(
&mut self,
typ: &str,
fn_ty: &'ll Type,
llfn: &'ll Value,
args: &'b [&'ll Value],
) -> Cow<'b, [&'ll Value]> {
assert!(
self.cx.type_kind(fn_ty) == TypeKind::Function,
"builder::{typ} not passed a function, but {fn_ty:?}"
);

let param_tys = self.cx.func_params_types(fn_ty);

let all_args_match = iter::zip(&param_tys, args.iter().map(|&v| self.cx.val_ty(v)))
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);

if all_args_match {
return Cow::Borrowed(args);
}

let casted_args: Vec<_> = iter::zip(param_tys, args)
.enumerate()
.map(|(i, (expected_ty, &actual_val))| {
let actual_ty = self.cx.val_ty(actual_val);
if expected_ty != actual_ty {
debug!(
"type mismatch in function call of {:?}. \
Expected {:?} for param {}, got {:?}; injecting bitcast",
llfn, expected_ty, i, actual_ty
);
self.bitcast(actual_val, expected_ty)
} else {
actual_val
}
})
.collect();

Cow::Owned(casted_args)
}
}

/// Empty string, to be used where LLVM expects an instruction name, indicating
/// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
// FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
@@ -1222,6 +1330,14 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
}

impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> {
let bx = Builder::with_cx(cx);
unsafe {
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
}
bx
}

fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
// Create a fresh builder from the crate context.
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
@@ -1231,13 +1347,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
pub(crate) fn llfn(&self) -> &'ll Value {
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
}
}

impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
unsafe {
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
}
}

}
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
fn align_metadata(&mut self, load: &'ll Value, align: Align) {
unsafe {
let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))];
@@ -1259,7 +1378,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
self.set_metadata(inst, llvm::MD_unpredictable, md);
}
}

}
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
}
@@ -1360,7 +1480,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
ret.expect("LLVM does not have support for catchret")
}
}

impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
fn check_call<'b>(
&mut self,
typ: &str,
@@ -1401,11 +1523,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {

Cow::Owned(casted_args)
}

}
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
}

}
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
let (ty, f) = self.cx.get_intrinsic(intrinsic);
self.call(ty, None, None, f, args, None, None)
@@ -1423,7 +1547,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {

self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
}

}
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
pub(crate) fn phi(
&mut self,
ty: &'ll Type,
@@ -1443,7 +1568,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
}
}

}
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
let src_ty = self.cx.val_ty(val);
let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector {
25 changes: 11 additions & 14 deletions compiler/rustc_codegen_llvm/src/builder/autodiff.rs
Original file line number Diff line number Diff line change
@@ -3,20 +3,19 @@ use std::ptr;
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivity, DiffMode};
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_ssa::back::write::ModuleConfig;
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
use rustc_errors::FatalError;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::Lto;
use tracing::{debug, trace};

use crate::back::write::{llvm_err, llvm_optimize};
use crate::builder::Builder;
use crate::declare::declare_raw_fn;
use crate::builder::SBuilder;
use crate::context::SimpleCx;
use crate::declare::declare_simple_fn;
use crate::errors::LlvmError;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{Metadata, True};
use crate::value::Value;
use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, context, llvm};
use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, llvm};

fn get_params(fnc: &Value) -> Vec<&Value> {
unsafe {
@@ -38,8 +37,8 @@ fn get_params(fnc: &Value) -> Vec<&Value> {
/// [^1]: <https://enzyme.mit.edu/getting_started/CallingConvention/>
// FIXME(ZuseZ4): `outer_fn` should include upstream safety checks to
// cover some assumptions of enzyme/autodiff, which could lead to UB otherwise.
fn generate_enzyme_call<'ll, 'tcx>(
cx: &context::CodegenCx<'ll, 'tcx>,
fn generate_enzyme_call<'ll>(
cx: &SimpleCx<'ll>,
fn_to_diff: &'ll Value,
outer_fn: &'ll Value,
attrs: AutoDiffAttrs,
@@ -112,7 +111,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
//FIXME(ZuseZ4): the CC/Addr/Vis values are best effort guesses, we should look at tests and
// think a bit more about what should go here.
let cc = llvm::LLVMGetFunctionCallConv(outer_fn);
let ad_fn = declare_raw_fn(
let ad_fn = declare_simple_fn(
cx,
&ad_name,
llvm::CallConv::try_from(cc).expect("invalid callconv"),
@@ -132,7 +131,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
llvm::LLVMRustEraseInstFromParent(br);

let last_inst = llvm::LLVMRustGetLastInstruction(entry).unwrap();
let mut builder = Builder::build(cx, entry);
let mut builder = SBuilder::build(cx, entry);

let num_args = llvm::LLVMCountParams(&fn_to_diff);
let mut args = Vec::with_capacity(num_args as usize + 1);
@@ -236,7 +235,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
}
}

let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None);
let call = builder.call(enzyme_ty, ad_fn, &args, None);

// This part is a bit iffy. LLVM requires that a call to an inlineable function has some
// metadata attachted to it, but we just created this code oota. Given that the
@@ -274,10 +273,9 @@ fn generate_enzyme_call<'ll, 'tcx>(
}
}

pub(crate) fn differentiate<'ll, 'tcx>(
pub(crate) fn differentiate<'ll>(
module: &'ll ModuleCodegen<ModuleLlvm>,
cgcx: &CodegenContext<LlvmCodegenBackend>,
tcx: TyCtxt<'tcx>,
diff_items: Vec<AutoDiffItem>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
@@ -286,8 +284,7 @@ pub(crate) fn differentiate<'ll, 'tcx>(
}

let diag_handler = cgcx.create_dcx();
let (_, cgus) = tcx.collect_and_partition_mono_items(());
let cx = context::CodegenCx::new(tcx, &cgus.first().unwrap(), &module.module_llvm);
let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx };

// Before dumping the module, we want all the TypeTrees to become part of the module.
for item in diff_items.iter() {
57 changes: 52 additions & 5 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::ffi::{CStr, c_char, c_uint};
use std::ops::Deref;
use std::str;

use rustc_abi::{HasDataLayout, TargetDataLayout, VariantIdx};
use rustc_codegen_ssa::back::versioned_llvm_target;
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
@@ -30,23 +32,46 @@ use smallvec::SmallVec;

use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn;
use crate::common::AsCCharPtr;
use crate::common::{self, AsCCharPtr};
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
use crate::llvm::{Metadata, MetadataType};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};

/// `TyCtxt` (and related cache datastructures) can't be move between threads.
/// However, there are various cx related functions which we want to be available to the builder and
/// other compiler pieces. Here we define a small subset which has enough information and can be
/// moved around more freely.
pub(crate) struct SimpleCx<'ll> {
pub llmod: &'ll llvm::Module,
pub llcx: &'ll llvm::Context,
}

impl<'ll> Borrow<SimpleCx<'ll>> for CodegenCx<'ll, '_> {
fn borrow(&self) -> &SimpleCx<'ll> {
&self.scx
}
}

impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
type Target = SimpleCx<'ll>;

#[inline]
fn deref(&self) -> &Self::Target {
&self.scx
}
}

/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
/// `llvm::Context` so that several codegen units may be processed in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
pub(crate) struct CodegenCx<'ll, 'tcx> {
pub tcx: TyCtxt<'tcx>,
pub scx: SimpleCx<'ll>,
pub use_dll_storage_attrs: bool,
pub tls_model: llvm::ThreadLocalMode,

pub llmod: &'ll llvm::Module,
pub llcx: &'ll llvm::Context,
pub codegen_unit: &'tcx CodegenUnit<'tcx>,

/// Cache instances of monomorphic and polymorphic items
@@ -553,10 +578,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {

CodegenCx {
tcx,
scx: SimpleCx { llcx, llmod },
use_dll_storage_attrs,
tls_model,
llmod,
llcx,
codegen_unit,
instances: Default::default(),
vtables: Default::default(),
@@ -600,6 +624,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
llvm::set_section(g, c"llvm.metadata");
}
}
}
impl<'ll> SimpleCx<'ll> {
pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type {
common::val_ty(v)
}

pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value {
unsafe { llvm::LLVMMetadataAsValue(self.llcx, metadata) }
@@ -625,6 +654,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
llvm::LLVMMDStringInContext2(self.llcx, name.as_ptr() as *const c_char, name.len())
})
}

pub(crate) fn type_kind(&self, ty: &'ll Type) -> TypeKind {
unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() }
}
}

impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@@ -1178,6 +1211,20 @@ impl CodegenCx<'_, '_> {
}
}

// This is a duplication of the set_metadata function above. However, so far it's the only one
// shared between both contexts, so it doesn't seem worth it to make the Cx generic like we did it
// for the Builder.
impl SimpleCx<'_> {
#[allow(unused)]
/// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`.
pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) {
unsafe {
let node = llvm::LLVMMetadataAsValue(&self.llcx, md);
llvm::LLVMSetMetadata(val, kind_id as c_uint, node);
}
}
}

impl HasDataLayout for CodegenCx<'_, '_> {
#[inline]
fn data_layout(&self) -> &TargetDataLayout {
28 changes: 23 additions & 5 deletions compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
@@ -21,26 +21,26 @@ use tracing::debug;

use crate::abi::{FnAbi, FnAbiLlvmExt};
use crate::common::AsCCharPtr;
use crate::context::CodegenCx;
use crate::context::{CodegenCx, SimpleCx};
use crate::llvm::AttributePlace::Function;
use crate::llvm::Visibility;
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, llvm};

/// Declare a function.
/// Declare a function with a SimpleCx.
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
pub(crate) fn declare_raw_fn<'ll>(
cx: &CodegenCx<'ll, '_>,
pub(crate) fn declare_simple_fn<'ll>(
cx: &SimpleCx<'ll>,
name: &str,
callconv: llvm::CallConv,
unnamed: llvm::UnnamedAddr,
visibility: llvm::Visibility,
ty: &'ll Type,
) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
debug!("declare_simple_fn(name={:?}, ty={:?})", name, ty);
let llfn = unsafe {
llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_c_char_ptr(), name.len(), ty)
};
@@ -49,6 +49,24 @@ pub(crate) fn declare_raw_fn<'ll>(
llvm::SetUnnamedAddress(llfn, unnamed);
llvm::set_visibility(llfn, visibility);

llfn
}

/// Declare a function.
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
pub(crate) fn declare_raw_fn<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
name: &str,
callconv: llvm::CallConv,
unnamed: llvm::UnnamedAddr,
visibility: llvm::Visibility,
ty: &'ll Type,
) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
let llfn = declare_simple_fn(cx, name, callconv, unnamed, visibility, ty);

let mut attrs = SmallVec::<[_; 4]>::new();

if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) {
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -1081,11 +1081,11 @@ fn codegen_emcc_try<'ll>(

// Helper function to give a Block to a closure to codegen a shim function.
// This is currently primarily used for the `try` intrinsic functions above.
fn gen_fn<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
fn gen_fn<'a, 'll, 'tcx>(
cx: &'a CodegenCx<'ll, 'tcx>,
name: &str,
rust_fn_sig: ty::PolyFnSig<'tcx>,
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
) -> (&'ll Type, &'ll Value) {
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty());
let llty = fn_abi.llvm_type(cx);
@@ -1104,9 +1104,9 @@ fn gen_fn<'ll, 'tcx>(
// catch exceptions.
//
// This function is only generated once and is then cached.
fn get_rust_try_fn<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
fn get_rust_try_fn<'a, 'll, 'tcx>(
cx: &'a CodegenCx<'ll, 'tcx>,
codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
) -> (&'ll Type, &'ll Value) {
if let Some(llfn) = cx.rust_try_fn.get() {
return llfn;
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -237,7 +237,6 @@ impl WriteBackendMethods for LlvmCodegenBackend {
/// Generate autodiff rules
fn autodiff(
cgcx: &CodegenContext<Self>,
tcx: TyCtxt<'_>,
module: &ModuleCodegen<Self::Module>,
diff_fncs: Vec<AutoDiffItem>,
config: &ModuleConfig,
@@ -246,7 +245,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
let dcx = cgcx.create_dcx();
return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutLTO));
}
builder::autodiff::differentiate(module, cgcx, tcx, diff_fncs, config)
builder::autodiff::differentiate(module, cgcx, diff_fncs, config)
}
}

13 changes: 7 additions & 6 deletions compiler/rustc_codegen_llvm/src/type_.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty};
use rustc_target::callconv::{CastTarget, FnAbi, Reg};

use crate::abi::{FnAbiLlvmExt, LlvmType};
use crate::context::CodegenCx;
use crate::context::{CodegenCx, SimpleCx};
pub(crate) use crate::llvm::Type;
use crate::llvm::{Bool, False, Metadata, True};
use crate::type_of::LayoutLlvmExt;
@@ -35,7 +35,8 @@ impl fmt::Debug for Type {
}
}

impl<'ll> CodegenCx<'ll, '_> {
impl<'ll> CodegenCx<'ll, '_> {}
impl<'ll> SimpleCx<'ll> {
pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type {
let name = SmallCStr::new(name);
unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) }
@@ -44,11 +45,9 @@ impl<'ll> CodegenCx<'ll, '_> {
pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
}

pub(crate) fn type_void(&self) -> &'ll Type {
unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
}

pub(crate) fn type_token(&self) -> &'ll Type {
unsafe { llvm::LLVMTokenTypeInContext(self.llcx) }
}
@@ -75,7 +74,8 @@ impl<'ll> CodegenCx<'ll, '_> {
args
}
}

}
impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
pub(crate) fn type_bool(&self) -> &'ll Type {
self.type_i8()
}
@@ -120,7 +120,8 @@ impl<'ll> CodegenCx<'ll, '_> {
assert_eq!(size % unit_size, 0);
self.type_array(self.type_from_integer(unit), size / unit_size)
}

}
impl<'ll> SimpleCx<'ll> {
pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
}
4 changes: 1 addition & 3 deletions compiler/rustc_codegen_ssa/src/back/lto.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ use std::sync::Arc;
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
use rustc_data_structures::memmap::Mmap;
use rustc_errors::FatalError;
use rustc_middle::ty::TyCtxt;

use super::write::CodegenContext;
use crate::ModuleCodegen;
@@ -89,13 +88,12 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
pub unsafe fn autodiff(
self,
cgcx: &CodegenContext<B>,
tcx: TyCtxt<'_>,
diff_fncs: Vec<AutoDiffItem>,
config: &ModuleConfig,
) -> Result<LtoModuleCodegen<B>, FatalError> {
match &self {
LtoModuleCodegen::Fat(module) => {
B::autodiff(cgcx, tcx, &module, diff_fncs, config)?;
B::autodiff(cgcx, &module, diff_fncs, config)?;
}
_ => panic!("autodiff called with non-fat LTO module"),
}
2 changes: 0 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/write.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
use rustc_errors::{DiagCtxtHandle, FatalError};
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::ty::TyCtxt;

use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig};
@@ -65,7 +64,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
fn autodiff(
cgcx: &CodegenContext<Self>,
tcx: TyCtxt<'_>,
module: &ModuleCodegen<Self::Module>,
diff_fncs: Vec<AutoDiffItem>,
config: &ModuleConfig,
9 changes: 9 additions & 0 deletions compiler/rustc_mir_build/src/builder/scope.rs
Original file line number Diff line number Diff line change
@@ -785,6 +785,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let local =
place.as_local().unwrap_or_else(|| bug!("projection in tail call args"));

if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) {
return None;
}

Some(DropData { source_info, local, kind: DropKind::Value })
}
Operand::Constant(_) => None,
@@ -795,6 +799,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.scopes.scopes.iter().rev().nth(1).unwrap().region_scope,
DUMMY_SP,
);
let typing_env = self.typing_env();
let unwind_drops = &mut self.scopes.unwind_drops;

// the innermost scope contains only the destructors for the tail call arguments
@@ -805,6 +810,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let source_info = drop_data.source_info;
let local = drop_data.local;

if !self.local_decls[local].ty.needs_drop(self.tcx, typing_env) {
continue;
}

match drop_data.kind {
DropKind::Value => {
// `unwind_to` should drop the value that we're about to
278 changes: 131 additions & 147 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -2571,9 +2571,11 @@ impl<T, A: Allocator> Vec<T, A> {
self.len += count;
}

/// Removes the specified range from the vector in bulk, returning all
/// removed elements as an iterator. If the iterator is dropped before
/// being fully consumed, it drops the remaining removed elements.
/// Removes the subslice indicated by the given range from the vector,
/// returning a double-ended iterator over the removed subslice.
///
/// If the iterator is dropped before being fully consumed,
/// it drops the remaining removed elements.
///
/// The returned iterator keeps a mutable borrow on the vector to optimize
/// its implementation.
20 changes: 20 additions & 0 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
@@ -90,6 +90,26 @@ impl_zeroable_primitive!(
///
/// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>());
/// ```
///
/// # Layout
///
/// `NonZero<T>` is guaranteed to have the same layout and bit validity as `T`
/// with the exception that the all-zero bit pattern is invalid.
/// `Option<NonZero<T>>` is guaranteed to be compatible with `T`, including in
/// FFI.
///
/// Thanks to the [null pointer optimization], `NonZero<T>` and
/// `Option<NonZero<T>>` are guaranteed to have the same size and alignment:
///
/// ```
/// # use std::mem::{size_of, align_of};
/// use std::num::NonZero;
///
/// assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
/// assert_eq!(align_of::<NonZero<u32>>(), align_of::<Option<NonZero<u32>>>());
/// ```
///
/// [null pointer optimization]: crate::option#representation
#[stable(feature = "generic_nonzero", since = "1.79.0")]
#[repr(transparent)]
#[rustc_nonnull_optimization_guaranteed]
1 change: 1 addition & 0 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
@@ -2529,6 +2529,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
/// limited to just these cases:
///
/// * The `original` path is not a file or doesn't exist.
/// * The 'link' path already exists.
///
/// # Examples
///
19 changes: 14 additions & 5 deletions src/doc/rustc-dev-guide/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -35,12 +35,13 @@ jobs:
~/.cargo/bin
key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}

- name: Cache linkcheck
uses: actions/cache@v4
- name: Restore cached Linkcheck
if: github.event_name == 'schedule'
id: cache-linkcheck-restore
uses: actions/cache/restore@v4
with:
path: |
~/book/linkcheck
key: ${{ runner.os }}-${{ hashFiles('./book/linkcheck') }}
path: book/linkcheck/cache.json
key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}

- name: Install latest nightly Rust toolchain
if: steps.mdbook-cache.outputs.cache-hit != 'true'
@@ -59,6 +60,14 @@ jobs:
- name: Check build
run: ENABLE_LINKCHECK=1 mdbook build

- name: Save cached Linkcheck
id: cache-linkcheck-save
if: ${{ !cancelled() && github.event_name == 'schedule' }}
uses: actions/cache/save@v4
with:
path: book/linkcheck/cache.json
key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}

- name: Deploy to gh-pages
if: github.event_name == 'push'
run: |
85 changes: 85 additions & 0 deletions src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: rustc-pull

on:
workflow_dispatch:
schedule:
# Run at 04:00 UTC every Monday
- cron: '0 4 * * 1'

jobs:
pull:
if: github.repository == 'rust-lang/rustc-dev-guide'
runs-on: ubuntu-latest
outputs:
pr_url: ${{ steps.update-pr.outputs.pr_url }}
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
# We need the full history for josh to work
fetch-depth: '0'
- name: Install stable Rust toolchain
run: rustup update stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: "josh-sync"
# Cache the josh directory with checked out rustc
cache-directories: "/home/runner/.cache/rustc-dev-guide-josh"
- name: Install josh
run: RUSTFLAGS="--cap-lints warn" cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
- name: Setup bot git name and email
run: |
git config --global user.name 'The rustc-dev-guide Cronjob Bot'
git config --global user.email 'github-actions@github.com'
- name: Perform rustc-pull
run: cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull
- name: Push changes to a branch
run: |
# Update a sticky branch that is used only for rustc pulls
BRANCH="rustc-pull"
git switch -c $BRANCH
git push -u origin $BRANCH --force
- name: Create pull request
id: update-pr
run: |
# Check if an open pull request for an rustc pull update already exists
# If it does, the previous push has just updated it
# If not, we create it now
RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title`
if [[ "$RESULT" -eq 0 ]]; then
echo "Creating new pull request"
PR_URL=gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.'
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
else
PR_URL=gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
send-zulip-message:
needs: [pull]
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
steps:
- name: Compute message
id: message
run: |
if [ "${{ needs.pull.result }}" == "failure" ];
then
WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT
else
echo "message=Rustc pull sync succeeded. Check out the [PR](${{ needs.pull.outputs.pr_url }})." >> $GITHUB_OUTPUT
fi
- name: Send a Zulip message about updated PR
uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5
with:
api-key: ${{ secrets.ZULIP_API_TOKEN }}
email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com"
organization-url: "https://rust-lang.zulipchat.com"
to: 196385
type: "stream"
topic: "Subtree sync automation"
content: ${{ steps.message.outputs.message }}
2 changes: 2 additions & 0 deletions src/doc/rustc-dev-guide/.gitignore
Original file line number Diff line number Diff line change
@@ -4,3 +4,5 @@ ci/date-check/target/

# Generated by check-in.sh
pulls.json

josh-sync/target
7 changes: 7 additions & 0 deletions src/doc/rustc-dev-guide/README.md
Original file line number Diff line number Diff line change
@@ -74,6 +74,13 @@ including the `<!-- toc -->` marker at the place where you want the TOC.

This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the following commands to synchronize the subtree in both directions.

You'll need to install `josh-proxy` locally via

```
cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
```
Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version.

### Pull changes from `rust-lang/rust` into this repository
1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide`
2) Run the pull command
4 changes: 3 additions & 1 deletion src/doc/rustc-dev-guide/book.toml
Original file line number Diff line number Diff line change
@@ -52,7 +52,9 @@ exclude = [
# 500 is returned for HEAD request
"code\\.visualstudio\\.com/docs/editor/tasks",
]
cache-timeout = 86400
# The scheduled CI runs every day and so we need to reuse a part of the cache
# in order to face "Server returned 429 Too Many Requests" errors for github.com.
cache-timeout = 90000
warning-policy = "error"

[output.html.redirect]
15 changes: 15 additions & 0 deletions src/doc/rustc-dev-guide/josh-sync/src/sync.rs
Original file line number Diff line number Diff line change
@@ -45,6 +45,11 @@ impl GitSync {
let josh_url =
format!("http://localhost:{JOSH_PORT}/{UPSTREAM_REPO}.git@{commit}{JOSH_FILTER}.git");

let previous_base_commit = sh.read_file("rust-version")?.trim().to_string();
if previous_base_commit == commit {
return Err(anyhow::anyhow!("No changes since last pull"));
}

// Update rust-version file. As a separate commit, since making it part of
// the merge has confused the heck out of josh in the past.
// We pass `--no-verify` to avoid running git hooks.
@@ -76,12 +81,22 @@ impl GitSync {
};
let num_roots_before = num_roots()?;

let sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;

// Merge the fetched commit.
const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc";
cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}")
.run()
.context("FAILED to merge new commits, something went wrong")?;

let current_sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;
if current_sha == sha {
cmd!(sh, "git reset --hard HEAD^")
.run()
.expect("FAILED to clean up after creating the preparation commit");
return Err(anyhow::anyhow!("No merge was performed, nothing to pull. Rolled back the preparation commit."));
}

// Check that the number of roots did not increase.
if num_roots()? != num_roots_before {
bail!("Josh created a new root commit. This is probably not the history you want.");
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dcfa38fe234de9304169afc6638e81d0dd222c06
ecda83b30f0f68cf5692855dddc0bc38ee8863fc
3 changes: 1 addition & 2 deletions src/doc/rustc-dev-guide/src/appendix/code-index.md
Original file line number Diff line number Diff line change
@@ -14,17 +14,16 @@ Item | Kind | Short description | Chapter |
`Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)
`DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/master/src/librustdoc/core.rs)
`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html)
`Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html)
`NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html)
`P` | struct | An owned immutable smart pointer. By contrast, `&T` is not owned, and `Box<T>` is not immutable. | None | [compiler/rustc_ast/src/ptr.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ptr/struct.P.html)
`ParamEnv` | struct | Information about generic parameters or `Self`, useful for working with associated or generic items | [Parameter Environment] | [compiler/rustc_middle/src/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html)
`ParseSess` | struct | This struct contains information about a parsing session | [The parser] | [compiler/rustc_session/src/parse/parse.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html)
`Query` | struct | Represents the result of query to the `Compiler` interface and allows stealing, borrowing, and returning the results of compiler passes. | [The Rustc Driver and Interface] | [compiler/rustc_interface/src/queries.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/queries/struct.Query.html)
`Rib` | struct | Represents a single scope of names | [Name resolution] | [compiler/rustc_resolve/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html)
`Session` | struct | The data associated with a compilation session | [The parser], [The Rustc Driver and Interface] | [compiler/rustc_session/src/session.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html)
`SourceFile` | struct | Part of the `SourceMap`. Maps AST nodes to their source code for a single source file. Was previously called FileMap | [The parser] | [compiler/rustc_span/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SourceFile.html)
`SourceMap` | struct | Maps AST nodes to their source code. It is composed of `SourceFile`s. Was previously called CodeMap | [The parser] | [compiler/rustc_span/src/source_map.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html)
`Span` | struct | A location in the user's source code, used for error reporting primarily | [Emitting Diagnostics] | [compiler/rustc_span/src/span_encoding.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html)
`StringReader` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html)
`rustc_ast::token_stream::TokenStream` | struct | An abstract sequence of tokens, organized into `TokenTree`s | [The parser], [Macro expansion] | [compiler/rustc_ast/src/tokenstream.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/tokenstream/struct.TokenStream.html)
`TraitDef` | struct | This struct contains a trait's definition with type information | [The `ty` modules] | [compiler/rustc_middle/src/ty/trait_def.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait_def/struct.TraitDef.html)
`TraitRef` | struct | The combination of a trait and its input types (e.g. `P0: Trait<P1...Pn>`) | [Trait Solving: Goals and Clauses] | [compiler/rustc_middle/src/ty/sty.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.TraitRef.html)
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/appendix/glossary.md
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ Term | Meaning
<span id="rib">rib</span> | A data structure in the name resolver that keeps track of a single scope for names. ([see more](../name-resolution.md))
<span id="rpit">RPIT</span> | A return-position `impl Trait`. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types)).
<span id="rpitit">RPITIT</span> | A return-position `impl Trait` in trait. Unlike RPIT, this is desugared to a generic associated type (GAT). Introduced in [RFC 3425](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). ([see more](../return-position-impl-trait-in-trait.md))
<span id="scrutinee">scrutinee</div> | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee.
<span id="scrutinee">scrutinee</span> | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee.
<span id="sess">`sess`</span> | The compiler _session_, which stores global data used throughout compilation
<span id="side-tables">side tables</span> | Because the [AST](#ast) and HIR are immutable once created, we often carry extra information about them in the form of hashtables, indexed by the id of a particular node.
<span id="sigil">sigil</span> | Like a keyword but composed entirely of non-alphanumeric tokens. For example, `&` is a sigil for references.
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ heavily on other parts of the crate. The separation of the code must not affect
the logic of the code nor its performance.

For these reasons, the separation process involves two transformations that
have to be done at the same time for the resulting code to compile :
have to be done at the same time for the resulting code to compile:

1. replace all the LLVM-specific types by generics inside function signatures
and structure definitions;
Original file line number Diff line number Diff line change
@@ -31,9 +31,9 @@ It starts by calling `fn try_promote_type_test_subject`. This function takes the

We then promote the `lower_bound` into the context of the caller. If the lower bound is equal to a placeholder, we replace it with `'static`

We then look at all universal regions `uv` which are required to outlive `lower_bound`, i.e. for which borrow checking adding region constraints. For each of these we then emit a `ClosureOutlivesRequirement` for non-local universal regions which are known to outlive `uv`.
We then look at all universal regions `uv` which are required to be outlived by `lower_bound`, i.e. for which borrow checking added region constraints. For each of these we then emit a `ClosureOutlivesRequirement` for all non-local universal regions which are known to outlive `uv`.

As we've already built the region graph of the closure at this point and emitted errors if that one is inconsistent, we are also able to assume that the outlive constraints `uv: lower_bound` hold.
As we've already built the region graph of the closure at this point and separately check that it is consistent, we are also able to assume the outlive constraints `uv: lower_bound` here.

So if we have a type-outlives bounds we can't prove, e.g. `T: 'local_infer`, we use the region graph to go to universal variables `'a` with `'a: local_infer`. In case `'a` are local, we then use the assumed outlived constraints to go to non-local ones.

2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/bug-fix-procedure.md
Original file line number Diff line number Diff line change
@@ -227,7 +227,7 @@ that we use for unstable features:
Ideally, breaking changes should have landed on the **stable branch** of the
compiler before they are finalized.

<a id="guide">
<a id="guide"></a>

### Removing a lint

2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/closure.md
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@ The other option is to step through the code using lldb or gdb.

1. `rust-lldb build/host/stage1/bin/rustc test.rs`
2. In lldb:
1. `b upvar.rs:134` // Setting the breakpoint on a certain line in the upvar.rs file`
1. `b upvar.rs:134` // Setting the breakpoint on a certain line in the upvar.rs file
2. `r` // Run the program until it hits the breakpoint

Let's start with [`upvar.rs`][upvar]. This file has something called
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/const-eval.md
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ Prominent examples are:
* need to be known to check for overlapping patterns

Additionally constant evaluation can be used to reduce the workload or binary
size at runtime by precomputing complex operations at compiletime and only
size at runtime by precomputing complex operations at compile time and only
storing the result.

All uses of constant evaluation can either be categorized as "influencing the type system"
62 changes: 1 addition & 61 deletions src/doc/rustc-dev-guide/src/contributing.md
Original file line number Diff line number Diff line change
@@ -422,68 +422,8 @@ Just a few things to keep in mind:

## Issue triage

Sometimes, an issue will stay open, even though the bug has been fixed.
And sometimes, the original bug may go stale because something has changed in the meantime.
Please see <https://forge.rust-lang.org/release/issue-triaging.html>.

It can be helpful to go through older bug reports and make sure that they are still valid.
Load up an older issue, double check that it's still true,
and leave a comment letting us know if it is or is not.
The [least recently updated sort][lru] is good for finding issues like this.

[Thanks to `@rustbot`][rustbot], anyone can help triage issues by adding
appropriate labels to issues that haven't been triaged yet:

[lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc
[rustbot]: ./rustbot.md

<style>
.label-color {
border-radius:0.5em;
}
table td:nth-child(2) {
white-space: nowrap;
}

</style>

| Labels | Color | Description |
|--------|-------|-------------|
| [A-] | <span class="label-color" style="background-color:#f7e101;">&#x2003;</span>&nbsp;Yellow | The **area** of the project an issue relates to. |
| [B-] | <span class="label-color" style="background-color:#d304cb;">&#x2003;</span>&nbsp;Magenta | Issues which are **blockers**. |
| [beta-] | <span class="label-color" style="background-color:#1e76d9;">&#x2003;</span>&nbsp;Dark Blue | Tracks changes which need to be [backported to beta][beta-backport] |
| [C-] | <span class="label-color" style="background-color:#f5f1fd;">&#x2003;</span>&nbsp;Light Purple | The **category** of an issue. |
| [D-] | <span class="label-color" style="background-color:#c9f7a3;">&#x2003;</span>&nbsp;Mossy Green | Issues for **diagnostics**. |
| [E-] | <span class="label-color" style="background-color:#02e10c;">&#x2003;</span>&nbsp;Green | The **experience** level necessary to fix an issue. |
| [F-] | <span class="label-color" style="background-color:#f9c0cc;">&#x2003;</span>&nbsp;Peach | Issues for **nightly features**. |
| [I-] | <span class="label-color" style="background-color:#e10c02;">&#x2003;</span>&nbsp;Red | The **importance** of the issue. |
| [I-\*-nominated] | <span class="label-color" style="background-color:#e10c02;">&#x2003;</span>&nbsp;Red | The issue has been nominated for discussion at the next meeting of the corresponding team. |
| [I-prioritize] | <span class="label-color" style="background-color:#e10c02;">&#x2003;</span>&nbsp;Red | The issue has been nominated for prioritization by the team tagged with a **T**-prefixed label. |
| [L-] | <span class="label-color" style="background-color:#64E9CF;">&#x2003;</span>&nbsp;Teal | The relevant **lint**. |
| [metabug] | <span class="label-color" style="background-color:#5319e7;">&#x2003;</span>&nbsp;Purple | Bugs that collect other bugs. |
| [O-] | <span class="label-color" style="background-color:#6e6ec0;">&#x2003;</span>&nbsp;Purple Grey | The **operating system** or platform that the issue is specific to. |
| [P-] | <span class="label-color" style="background-color:#eb6420;">&#x2003;</span>&nbsp;Orange | The issue **priority**. These labels can be assigned by anyone that understand the issue and is able to prioritize it, and remove the [I-prioritize] label. |
| [regression-] | <span class="label-color" style="background-color:#e4008a;">&#x2003;</span>&nbsp;Pink | Tracks regressions from a stable release. |
| [relnotes] | <span class="label-color" style="background-color:#fad8c7;">&#x2003;</span>&nbsp;Light Orange | Changes that should be documented in the release notes of the next release. |
| [S-] | <span class="label-color" style="background-color:#d3dddd;">&#x2003;</span>&nbsp;Gray | Tracks the **status** of pull requests. |
| [S-tracking-] | <span class="label-color" style="background-color:#4682b4;">&#x2003;</span>&nbsp;Steel Blue | Tracks the **status** of [tracking issues]. |
| [stable-] | <span class="label-color" style="background-color:#00229c;">&#x2003;</span>&nbsp;Dark Blue | Tracks changes which need to be [backported to stable][stable-backport] in anticipation of a point release. |
| [T-] | <span class="label-color" style="background-color:#bfd4f2;">&#x2003;</span>&nbsp;Blue | Denotes which **team** the issue belongs to. |
| [WG-] | <span class="label-color" style="background-color:#c2e0c6;">&#x2003;</span>&nbsp;Green | Denotes which **working group** the issue belongs to. |


[A-]: https://github.com/rust-lang/rust/labels?q=A
[B-]: https://github.com/rust-lang/rust/labels?q=B
[C-]: https://github.com/rust-lang/rust/labels?q=C
[D-]: https://github.com/rust-lang/rust/labels?q=D
[E-]: https://github.com/rust-lang/rust/labels?q=E
[F-]: https://github.com/rust-lang/rust/labels?q=F
[I-]: https://github.com/rust-lang/rust/labels?q=I
[L-]: https://github.com/rust-lang/rust/labels?q=L
[O-]: https://github.com/rust-lang/rust/labels?q=O
[P-]: https://github.com/rust-lang/rust/labels?q=P
[S-]: https://github.com/rust-lang/rust/labels?q=S
[T-]: https://github.com/rust-lang/rust/labels?q=T
[WG-]: https://github.com/rust-lang/rust/labels?q=WG
[stable-]: https://github.com/rust-lang/rust/labels?q=stable
[beta-]: https://github.com/rust-lang/rust/labels?q=beta
[I-\*-nominated]: https://github.com/rust-lang/rust/labels?q=nominated
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/diagnostics.md
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ Here are a few examples:
their crate, making this a hard error would make refactoring and development
very painful.
- [future-incompatible lints]:
these are silencable lints.
these are silenceable lints.
It was decided that making them fixed errors would cause too much breakage,
so warnings are instead emitted,
and will eventually be turned into fixed (hard) errors.
6 changes: 5 additions & 1 deletion src/doc/rustc-dev-guide/src/external-repos.md
Original file line number Diff line number Diff line change
@@ -18,9 +18,11 @@ The following external projects are managed using some form of a `subtree`:

* [clippy](https://github.com/rust-lang/rust-clippy)
* [miri](https://github.com/rust-lang/miri)
* [portable-simd](https://github.com/rust-lang/portable-simd)
* [rustfmt](https://github.com/rust-lang/rustfmt)
* [rust-analyzer](https://github.com/rust-lang/rust-analyzer)
* [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift)
* [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide)

In contrast to `submodule` dependencies
(see below for those), the `subtree` dependencies are just regular files and directories which can
@@ -33,13 +35,15 @@ implement a new tool feature or test, that should happen in one collective rustc

* Using `git subtree`
* `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy))
* `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh))
* `rustfmt`
* `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7))
* Using the [josh] tool
* `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo))
* `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147))
* `rustc-dev-guide` ([sync guide](https://github.com/rust-lang/rustc-dev-guide#synchronizing-josh-subtree-with-rustc))

The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a subtree from `git subtree` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg).
The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a repository dependency from `git subtree` or `git submodule` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg).

Below you can find a guide on how to perform push and pull synchronization with the main rustc repo using `git subtree`, although these instructions might differ repo from repo.

4 changes: 2 additions & 2 deletions src/doc/rustc-dev-guide/src/guides/editions.md
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ stability.
## Edition parsing

For the most part, the lexer is edition-agnostic.
Within [`StringReader`], tokens can be modified based on edition-specific behavior.
Within [`Lexer`], tokens can be modified based on edition-specific behavior.
For example, C-String literals like `c"foo"` are split into multiple tokens in editions before 2021.
This is also where things like reserved prefixes are handled for the 2021 edition.

@@ -114,7 +114,7 @@ For example, the deprecated `start...end` pattern syntax emits the
[`ellipsis_inclusive_range_patterns`] lint on editions before 2021, and in 2021 is an hard error via
the `emit_err` method.

[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html
[`ParseSess::edition`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html#structfield.edition
[`ellipsis_inclusive_range_patterns`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#ellipsis-inclusive-range-patterns

Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ If that fails, we reveal the hidden type of the opaque type,
but only to prove this specific trait bound, not in general.
Revealing is done by invoking the `type_of` query on the `DefId` of the opaque type.
The query will internally request the hidden types from the defining function(s)
and return that (see [the section on `type_of`](#Within-the-type_of-query) for more details).
and return that (see [the section on `type_of`](#within-the-type_of-query) for more details).

#### Flowchart of type checking steps

4 changes: 2 additions & 2 deletions src/doc/rustc-dev-guide/src/overview.md
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ Unicode character encoding.

The token stream passes through a higher-level lexer located in
[`rustc_parse`] to prepare for the next stage of the compile process. The
[`StringReader`] `struct` is used at this stage to perform a set of validations
[`Lexer`] `struct` is used at this stage to perform a set of validations
and turn strings into interned symbols (_interning_ is discussed later).
[String interning] is a way of storing only one immutable
copy of each distinct string value.
@@ -153,7 +153,7 @@ the final binary.
[`rustc_parse::parser::Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html
[`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[`simplify_try`]: https://github.com/rust-lang/rust/pull/66282
[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html
[`Ty<'tcx>`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
[borrow checking]: borrow_check.md
[codegen]: backend/codegen.md
4 changes: 2 additions & 2 deletions src/doc/rustc-dev-guide/src/solve/caching.md
Original file line number Diff line number Diff line change
@@ -98,8 +98,8 @@ TODO: write this :3
[req-depth-ck]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_middle/src/traits/solve/cache.rs#L76-L86
[update-depth]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_trait_selection/src/solve/search_graph.rs#L308
[rem-depth]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_middle/src/traits/solve/cache.rs#L124
[^1]: This is overly restrictive: if all nested goal return the overflow response with some
availabledepth `n`, then their result should be the same for any depths smaller than `n`.
[^1]: This is overly restrictive: if all nested goals return the overflow response with some
available depth `n`, then their result should be the same for any depths smaller than `n`.
We can implement this optimization in the future.

[chapter on coinduction]: ./coinduction.md
7 changes: 2 additions & 5 deletions src/doc/rustc-dev-guide/src/solve/invariants.md
Original file line number Diff line number Diff line change
@@ -23,17 +23,14 @@ well-formed after normalizing said aliases. We rely on this as
otherwise we would have to re-check for well-formedness for these
types.

This is unfortunately broken for `<fndef as FnOnce<..>>::Output` due to implied bounds,
resulting in [#114936].

### Structural equality modulo regions implies semantic equality ✅

If you have a some type and equate it to itself after replacing any regions with unique
inference variables in both the lhs and rhs, the now potentially structurally different
types should still be equal to each other.

Needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck.
If this does invariant is broken MIR typeck ends up failing with an ICE.
If this invariant is broken MIR typeck ends up failing with an ICE.

### Applying inference results from a goal does not change its result ❌

@@ -91,7 +88,7 @@ it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/

If a trait goal holds with an empty environment, there should be a unique `impl`,
either user-defined or builtin, which is used to prove that goal. This is
necessary to select a unique method. It
necessary to select a unique method.

We do however break this invariant in few cases, some of which are due to bugs,
some by design:
4 changes: 2 additions & 2 deletions src/doc/rustc-dev-guide/src/solve/the-solver.md
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ a separate "probe", to not leak inference constraints to the other candidates.
We then try to merge the assembled candidates via `EvalCtxt::merge_candidates`.


## Important concepts and design pattern
## Important concepts and design patterns

### `EvalCtxt::add_goal`

@@ -64,7 +64,7 @@ eagerly instantiates `'a` with a placeholder and then recursively proves
Some goals can be proven in multiple ways. In these cases we try each option in
a separate "probe" and then attempt to merge the resulting responses by using
`EvalCtxt::try_merge_responses`. If merging the responses fails, we use
`EvalCtxt::flounder` instead, returning ambiguity. For some goals, we try
`EvalCtxt::flounder` instead, returning ambiguity. For some goals, we try to
incompletely prefer some choices over others in case `EvalCtxt::try_merge_responses`
fails.

19 changes: 17 additions & 2 deletions src/doc/rustc-dev-guide/src/tests/ci.md
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined
in [`.github/workflows/ci.yml`], which contains a bunch of steps that are
unified for all CI jobs that we execute. When a commit is pushed to a
corresponding branch or a PR, the workflow executes the
[`ci.py`] script, which dynamically generates the specific CI
[`src/ci/github-actions/ci.py`] script, which dynamically generates the specific CI
jobs that should be executed. This script uses the [`jobs.yml`] file as an
input, which contains a declarative configuration of all our CI jobs.

@@ -409,10 +409,25 @@ To learn more about the dashboard, see the [Datadog CI docs].
[Datadog CI docs]: https://docs.datadoghq.com/continuous_integration/
[public dashboard]: https://p.datadoghq.com/sb/3a172e20-e9e1-11ed-80e3-da7ad0900002-b5f7bb7e08b664a06b08527da85f7e30

## Determining the CI configuration

If you want to determine which `config.toml` settings are used in CI for a
particular job, it is probably easiest to just look at the build log. To do
this:

1. Go to
<https://github.com/rust-lang-ci/rust/actions?query=branch%3Aauto+is%3Asuccess>
to find the most recently successful build, and click on it.
2. Choose the job you are interested in on the left-hand side.
3. Click on the gear icon and choose "View raw logs"
4. Search for the string "Configure the build"
5. All of the build settings are listed below that starting with the
`configure:` prefix.

[GitHub Actions]: https://github.com/rust-lang/rust/actions
[`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml
[`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml
[`ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py
[`src/ci/github-actions/ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py
[rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions
[bors]: https://github.com/bors
[homu]: https://github.com/rust-lang/homu
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/tests/directives.md
Original file line number Diff line number Diff line change
@@ -252,7 +252,7 @@ Consider writing the test as a proper incremental test instead.

| Directive | Explanation | Supported test suites | Possible values |
|-------------|--------------------------------------------------------------|------------------------------------------|---------------------------|
| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `js-doc-test`, `rustdoc-json` | Any valid `rustdoc` flags |
| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json` | Any valid `rustdoc` flags |

<!--
**FIXME(rustdoc)**: what does `check-test-line-numbers-match` do?
6 changes: 3 additions & 3 deletions src/doc/rustc-dev-guide/src/the-parser.md
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ the token stream, and then execute the parser to get a [`Crate`] (the root AST
node).

To minimize the amount of copying that is done,
both [`StringReader`] and [`Parser`] have lifetimes which bind them to the parent [`ParseSess`].
both [`Lexer`] and [`Parser`] have lifetimes which bind them to the parent [`ParseSess`].
This contains all the information needed while parsing, as well as the [`SourceMap`] itself.

Note that while parsing, we may encounter macro definitions or invocations.
@@ -67,7 +67,7 @@ Code for lexical analysis is split between two crates:
constituting tokens. Although it is popular to implement lexers as generated
finite state machines, the lexer in [`rustc_lexer`] is hand-written.

- [`StringReader`] integrates [`rustc_lexer`] with data structures specific to
- [`Lexer`] integrates [`rustc_lexer`] with data structures specific to
`rustc`. Specifically, it adds `Span` information to tokens returned by
[`rustc_lexer`] and interns identifiers.

@@ -76,7 +76,7 @@ Code for lexical analysis is split between two crates:
[`ParseSess`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html
[`rustc_lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html
[`SourceMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html
[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html
[ast module]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html
[ast]: ./ast-validation.md
[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/index.html
4 changes: 2 additions & 2 deletions src/doc/rustc-dev-guide/src/traits/implied-bounds.md
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ requirements of impls and functions as explicit predicates.

These bounds are not added to the `ParamEnv` of the affected item itself. For lexical
region resolution they are added using [`fn OutlivesEnvironment::with_bounds`].
Similarly,during MIR borrowck we add them using
Similarly, during MIR borrowck we add them using
[`fn UniversalRegionRelationsBuilder::add_implied_bounds`].

[We add implied bounds for the function signature and impl header in MIR borrowck][mir].
@@ -81,4 +81,4 @@ This results in multiple unsoundnesses:

[#25860]: https://github.com/rust-lang/rust/issues/25860
[#84591]: https://github.com/rust-lang/rust/issues/84591
[#100051]: https://github.com/rust-lang/rust/issues/100051
[#100051]: https://github.com/rust-lang/rust/issues/100051
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/ty_module/binders.md
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ Usages of these parameters is represented by the `RegionKind::Bound` (or `TyKind
- A [`BoundVar`] which specifies which of the parameters the `Binder` introduces we are referring to.
- We also sometimes store some extra information for diagnostics reasons via the [`BoundTyKind`]/[`BoundRegionKind`] but this is not important for type equality or more generally the semantics of `Ty`. (omitted from the above example)

In debug output (and also informally when talking to eachother) we tend to write these bound variables in the format of `^DebruijnIndex_BoundVar`. The above example would instead be written as `Binder(fn(&'^0_0), &[BoundVariableKind::Region])`. Sometimes when the `DebruijnIndex` is `0` we just omit it and would write `^0`.
In debug output (and also informally when talking to each other) we tend to write these bound variables in the format of `^DebruijnIndex_BoundVar`. The above example would instead be written as `Binder(fn(&'^0_0), &[BoundVariableKind::Region])`. Sometimes when the `DebruijnIndex` is `0` we just omit it and would write `^0`.

Another concrete example, this time a mixture of `for<'a>` in a where clause and a type:
```
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/ty_module/early_binder.md
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ fn bar(foo: Foo<u32, f32>) {
In the compiler the `instantiate` call for this is done in [`FieldDef::ty`] ([src][field_def_ty_src]), at some point during type checking `bar` we will wind up calling `FieldDef::ty(x, &[u32, f32])` in order to obtain the type of `foo.x`.

**Note on indices:** It is a bug if the index of a `Param` does not match what the `EarlyBinder` binds. For
example, if the index is out of bounds or the index index of a lifetime corresponds to a type parameter.
example, if the index is out of bounds or the index of a lifetime corresponds to a type parameter.
These sorts of errors are caught earlier in the compiler during name resolution where we disallow references
to generics parameters introduced by items that should not be nameable by the inner item.

Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ Concretely given the `ty::Generics` for the item the parameter is defined on, if

The index fully defines the `Ty` and is the only part of `TyKind::Param` that matters for reasoning about the code we are compiling.

Generally we do not care what the name is and only use the index is included for diagnostics and debug logs as otherwise it would be
Generally we do not care what the name is and only use the index. The name is included for diagnostics and debug logs as otherwise it would be
incredibly difficult to understand the output, i.e. `Vec<Param(0)>: Sized` vs `Vec<T>: Sized`. In debug output, parameter types are
often printed out as `{name}/#{index}`, for example in the function `foo` if we were to debug print `Vec<T>` it would be written as `Vec<T/#0>`.

@@ -65,7 +65,7 @@ The rules against shadowing make this difficult but those language rules could c

### Lifetime parameters

In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`]. The reason for this is due to function's distinguishing between [early and late bound parameters](../early-late-bound-params/early-late-bound-summary.md) which is discussed in an earlier chapter (see link).
In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`]. The reason for this is due to function's distinguishing between [early and late bound parameters][ch_early_late_bound] which is discussed in an earlier chapter (see link).

`RegionKind::EarlyParam` is structured identically to `Ty/Const`'s `Param` variant, it is simply a `u32` index and a `Symbol`. For lifetime parameters defined on non-function items we always use `ReEarlyParam`. For functions we use `ReEarlyParam` for any early bound parameters and `ReLateParam` for any late bound parameters. Note that just like `Ty` and `Const` params we often debug format them as `'SYMBOL/#INDEX`, see for example:

@@ -85,7 +85,7 @@ fn foo<'a, 'b, T: 'a>(one: T, two: &'a &'b u32) -> &'b u32 {

`RegionKind::LateParam` will be discussed more in the chapter on [instantiating binders][ch_instantiating_binders].

[ch_early_late_bound]: ../early-late-bound-params/early-late-bound-summary.md
[ch_early_late_bound]: ../early_late_parameters.md
[ch_binders]: ./binders.md
[ch_instantiating_binders]: ./instantiating_binders.md
[`BoundRegionKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.BoundRegionKind.html
3 changes: 3 additions & 0 deletions src/doc/rustc-dev-guide/triagebot.toml
Original file line number Diff line number Diff line change
@@ -6,3 +6,6 @@ allow-unauthenticated = [
"waiting-on-author",
"blocked",
]

# Automatically close and reopen PRs made by bots to run CI on them
[bot-pull-requests]
10 changes: 7 additions & 3 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
@@ -2166,7 +2166,8 @@ details.toggle > summary:not(.hideme)::before {
top: 4px;
}

.impl-items > details.toggle > summary:not(.hideme)::before {
.impl-items > details.toggle > summary:not(.hideme)::before,
#main-content > .methods > details.toggle > summary:not(.hideme)::before {
position: absolute;
left: -24px;
}
@@ -2176,7 +2177,9 @@ details.toggle > summary:not(.hideme)::before {
.impl-items > *:not(.item-info),
/* We also indent the first top doc comment the same to still keep an indent on the
doc block while aligning it with the impl block items. */
.implementors-toggle > .docblock {
.implementors-toggle > .docblock,
/* We indent trait items as well. */
#main-content > .methods > :not(.item-info) {
margin-left: var(--impl-items-indent);
}

@@ -2508,7 +2511,8 @@ in src-script.js and main.js
margin-left: 10px;
}

.impl-items > details.toggle > summary:not(.hideme)::before {
.impl-items > details.toggle > summary:not(.hideme)::before,
#main-content > .methods > details.toggle > summary:not(.hideme)::before {
left: -20px;
}

Original file line number Diff line number Diff line change
@@ -14,8 +14,8 @@ LL | let local = 0;
help: ALLOC was deallocated here:
--> tests/fail/tail_calls/dangling-local-var.rs:LL:CC
|
LL | }
| ^
LL | become g(ptr)
| ^^^^^^^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `g` at tests/fail/tail_calls/dangling-local-var.rs:LL:CC
note: inside `main`
6 changes: 0 additions & 6 deletions tests/crashes/128097.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -66,7 +66,6 @@
bb6: {
+ _8 = const false;
StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb12];
}

Original file line number Diff line number Diff line change
@@ -66,7 +66,6 @@
bb6: {
+ _8 = const false;
StorageDead(_4);
StorageDead(_3);
- drop(_2) -> [return: bb7, unwind continue];
+ drop(_2) -> [return: bb7, unwind: bb12];
}
Original file line number Diff line number Diff line change
@@ -63,7 +63,6 @@ fn f() -> () {

bb6: {
StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb17];
}

Original file line number Diff line number Diff line change
@@ -63,7 +63,6 @@ fn f() -> () {

bb6: {
StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb17];
}

Original file line number Diff line number Diff line change
@@ -80,7 +80,6 @@
bb8: {
+ _12 = const false;
StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb16];
}

Original file line number Diff line number Diff line change
@@ -80,7 +80,6 @@
bb8: {
+ _12 = const false;
StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb16];
}

Original file line number Diff line number Diff line change
@@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () {

bb8: {
StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb23];
}

Original file line number Diff line number Diff line change
@@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () {

bb8: {
StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb23];
}

2 changes: 1 addition & 1 deletion tests/rustdoc-gui/search-tab.goml
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ call-function: ("check-colors", {
set-window-size: (851, 600)

// Check the size and count in tabs
assert-text: ("#search-tabs > button:nth-child(1) > .count", " (26) ")
assert-text: ("#search-tabs > button:nth-child(1) > .count", " (27) ")
assert-text: ("#search-tabs > button:nth-child(2) > .count", " (7)  ")
assert-text: ("#search-tabs > button:nth-child(3) > .count", " (0)  ")
store-property: ("#search-tabs > button:nth-child(1)", {"offsetWidth": buttonWidth})
22 changes: 22 additions & 0 deletions tests/rustdoc-gui/src/test_docs/lib.rs
Original file line number Diff line number Diff line change
@@ -691,3 +691,25 @@ impl ImplDoc {
impl ImplDoc {
pub fn bar5() {}
}

pub trait ItemsTrait {
/// You want doc, here is doc!
///
/// blablala
type F;

/// You want doc, here is doc!
///
/// blablala
const X: u32;

/// You want doc, here is doc!
///
/// blablala
fn foo() {}

/// You want doc, here is doc!
///
/// blablala
fn bar();
}
26 changes: 26 additions & 0 deletions tests/rustdoc-gui/toggle-docs-mobile.goml
Original file line number Diff line number Diff line change
@@ -31,3 +31,29 @@ assert-attribute: (".top-doc", {"open": ""})
// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
click: (3, 270)
assert-attribute: (".top-doc", {"open": ""})

// Same check on trait items.
fail-on-request-error: false // To prevent downloads errors on "trait.impl/test_docs/trait.ItemsTrait.js"
go-to: "file://" + |DOC_PATH| + "/test_docs/trait.ItemsTrait.html"

define-function: (
"check-trait-item",
[nth, text],
block {
store-value: (selector, ".methods:nth-of-type(" + |nth| + ") > details summary")
assert-text: (|selector| + " h4", |text|)
assert-position: (
|selector| + "::before",
{"x": 6},
)
},
)

// Assert the position of the toggle on an associated const.
call-function: ("check-trait-item", {"nth": 2, "text": "const X: u32"})
// Assert the position of the toggle on an associated type.
call-function: ("check-trait-item", {"nth": 3, "text": "type F"})
// Assert the position of the toggle on an associated required method.
call-function: ("check-trait-item", {"nth": 4, "text": "fn bar()"})
// Assert the position of the toggle on an associated provided method.
call-function: ("check-trait-item", {"nth": 5, "text": "fn foo()"})
17 changes: 17 additions & 0 deletions tests/ui/diagnostic-width/secondary-label-with-long-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes
//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
type A = (i32, i32, i32, i32);
type B = (A, A, A, A);
type C = (B, B, B, B);
type D = (C, C, C, C);

fn foo(x: D) {
let () = x; //~ ERROR mismatched types
//~^ NOTE this expression has type `((...,
//~| NOTE expected `((...,
//~| NOTE expected tuple
//~| NOTE the full type name has been written to
//~| NOTE consider using `--verbose` to print the full type name to the console
}

fn main() {}
16 changes: 16 additions & 0 deletions tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0308]: mismatched types
--> $DIR/secondary-label-with-long-type.rs:9:9
|
LL | let () = x;
| ^^ - this expression has type `((..., ..., ..., ...), ..., ..., ...)`
| |
| expected `((..., ..., ..., ...), ..., ..., ...)`, found `()`
|
= note: expected tuple `((..., ..., ..., ...), ..., ..., ...)`
found unit type `()`
= note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/secondary-label-with-long-type/secondary-label-with-long-type.long-type-hash.txt'
= note: consider using `--verbose` to print the full type name to the console

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
7 changes: 3 additions & 4 deletions tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr
Original file line number Diff line number Diff line change
@@ -4,10 +4,9 @@ error[E0597]: `local` does not live long enough
LL | let local = Type;
| ----- binding `local` declared here
LL | become takes_borrow(&local);
| ^^^^^^ borrowed value does not live long enough
LL |
LL | }
| - `local` dropped here while still borrowed
| ^^^^^^- `local` dropped here while still borrowed
| |
| borrowed value does not live long enough

error: aborting due to 1 previous error

14 changes: 14 additions & 0 deletions tests/ui/explicit-tail-calls/two-phase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// regression test for <https://github.com/rust-lang/rust/issues/112788>.
// this test used to ICE because we tried to run drop glue of `x`
// if dropping `_y` (happening at the `become` site) panicked and caused an unwind.
//
//@ check-pass
#![expect(incomplete_features)]
#![feature(explicit_tail_calls)]

fn f(x: &mut ()) {
let _y = String::new();
become f(x);
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ LL | assert_eq!(smart_ptr.a::<&Foo>(), 2);
| ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
|
= note: expected reference `&Foo`
found struct `SmartPtr<'_, Foo, >`
found struct `SmartPtr<'_, Foo>`

error[E0308]: mismatched types
--> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:62:16
@@ -62,7 +62,7 @@ LL | assert_eq!(smart_ptr.b::<&Foo>(), 1);
| ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
|
= note: expected reference `&Foo`
found struct `SmartPtr<'_, Foo, >`
found struct `SmartPtr<'_, Foo>`

error: aborting due to 8 previous errors

Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ LL | smart_ptr.get::<&Foo>();
| ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
|
= note: expected reference `&Foo`
found struct `SmartPtr<'_, Foo, >`
found struct `SmartPtr<'_, Foo>`

error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
--> $DIR/arbitrary-self-from-method-substs.rs:92:9
8 changes: 4 additions & 4 deletions tests/ui/typeck/ice-self-mismatch-const-generics.stderr
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ LL | pub fn new(thing: T) -> GenericStruct<1, T> {
LL | Self { thing }
| ^^^^^^^^^^^^^^ expected `1`, found `0`
|
= note: expected struct `GenericStruct<_, 1>`
found struct `GenericStruct<_, 0>`
= note: expected struct `GenericStruct<1, _>`
found struct `GenericStruct<0, _>`
help: use the type name directly
|
LL | GenericStruct::<1, T> { thing }
@@ -25,8 +25,8 @@ LL | pub fn new(thing: T) -> GenericStruct2<1, T> {
LL | Self { 0: thing }
| ^^^^^^^^^^^^^^^^^ expected `1`, found `0`
|
= note: expected struct `GenericStruct2<_, 1>`
found struct `GenericStruct2<_, 0>`
= note: expected struct `GenericStruct2<1, _>`
found struct `GenericStruct2<0, _>`
help: use the type name directly
|
LL | GenericStruct2::<1, T> { 0: thing }