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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-08-20"
channel = "nightly-2026-05-01"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(rustc_private)]

fn main() {
fn main() -> std::process::ExitCode {
env_logger::init();
rustc_plugin::cli_main(print_all_items::PrintAllItemsPlugin);
rustc_plugin::cli_main(print_all_items::PrintAllItemsPlugin)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(rustc_private)]

fn main() {
fn main() -> std::process::ExitCode {
env_logger::init();
rustc_plugin::driver_main(print_all_items::PrintAllItemsPlugin);
rustc_plugin::driver_main(print_all_items::PrintAllItemsPlugin)
}
11 changes: 7 additions & 4 deletions crates/rustc_plugin/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{
env, fs,
path::PathBuf,
process::{Command, Stdio, exit},
process::{Command, ExitCode, Stdio},
};

use cargo_metadata::camino::Utf8Path;
Expand All @@ -15,10 +15,10 @@ pub const SPECIFIC_TARGET: &str = "SPECIFIC_TARGET";
pub const CARGO_VERBOSE: &str = "CARGO_VERBOSE";

/// The top-level function that should be called in your user-facing binary.
pub fn cli_main<T: RustcPlugin>(plugin: T) {
pub fn cli_main<T: RustcPlugin>(plugin: T) -> ExitCode {
if env::args().any(|arg| arg == "-V") {
println!("{}", plugin.version());
return;
return ExitCode::SUCCESS;
}

let metadata = cargo_metadata::MetadataCommand::new()
Expand Down Expand Up @@ -95,7 +95,10 @@ pub fn cli_main<T: RustcPlugin>(plugin: T) {

let exit_status = cmd.status().expect("failed to wait for cargo?");

exit(exit_status.code().unwrap_or(-1));
match exit_status.code() {
Some(code) => ExitCode::from(u8::try_from(code).unwrap()),
None => ExitCode::FAILURE,
}
}

fn only_run_on_file(
Expand Down
8 changes: 4 additions & 4 deletions crates/rustc_plugin/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{
env,
ops::Deref,
path::{Path, PathBuf},
process::{Command, exit},
process::{Command, ExitCode, exit},
};

use rustc_session::{EarlyDiagCtxt, config::ErrorOutputType};
Expand Down Expand Up @@ -99,11 +99,11 @@ struct DefaultCallbacks;
impl rustc_driver::Callbacks for DefaultCallbacks {}

/// The top-level function that should be called by your internal driver binary.
pub fn driver_main<T: RustcPlugin>(plugin: T) {
pub fn driver_main<T: RustcPlugin>(plugin: T) -> ExitCode {
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
rustc_driver::init_rustc_env_logger(&early_dcx);

exit(rustc_driver::catch_with_exit_code(move || {
rustc_driver::catch_with_exit_code(move || {
let mut orig_args: Vec<String> = env::args().collect();

let (have_sys_root_arg, sys_root) = get_sysroot(&orig_args);
Expand Down Expand Up @@ -157,7 +157,7 @@ is_target_crate={is_target_crate}"
);
rustc_driver::run_compiler(&args, &mut DefaultCallbacks);
}
}))
})
}

fn is_target_crate(args: &[String]) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustc_utils"
version = "0.14.3-nightly-2025-08-20"
version = "0.15.0-nightly-2026-05-01"
edition = "2024"
authors = ["Will Crichton <crichton.will@gmail.com>"]
description = "Utilities for working with the Rust compiler"
Expand Down
4 changes: 2 additions & 2 deletions crates/rustc_utils/src/hir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl<'tcx> TyExt<'tcx> for Ty<'tcx> {
use rustc_infer::traits::EvaluationResult;

let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
let ty = tcx.erase_regions(self);
let ty = tcx.erase_and_anonymize_regions(self);
let result = infcx.type_implements_trait(trait_def_id, [ty], param_env);
matches!(
result,
Expand All @@ -50,7 +50,7 @@ impl<'tcx> TyExt<'tcx> for Ty<'tcx> {
}

fn is_copyable(self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>) -> bool {
let ty = tcx.erase_regions(self);
let ty = tcx.erase_and_anonymize_regions(self);
tcx.type_is_copy_modulo_regions(typing_env, ty)
}
}
Expand Down
5 changes: 0 additions & 5 deletions crates/rustc_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,8 @@

#![feature(
rustc_private,
negative_impls, // for !Send
min_specialization, // for rustc_index::newtype_index
type_alias_impl_trait, // for iterators in traits
box_patterns, // for ergonomics
exact_size_is_empty, // for graphviz module
impl_trait_in_assoc_type,
doc_auto_cfg, // for feature gates in documentation
)]
#![warn(clippy::pedantic)]
#![allow(
Expand Down
13 changes: 2 additions & 11 deletions crates/rustc_utils/src/mir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ use std::{
};

use anyhow::{Result, ensure};
use pretty::PrettyPrintMirOptions;
use rustc_data_structures::fx::FxHashMap as HashMap;
use rustc_hir::{CoroutineDesugaring, CoroutineKind, HirId, def_id::DefId};
use rustc_middle::{
mir::{
BasicBlock, Body, Local, Location, Place, SourceInfo, TerminatorKind,
VarDebugInfoContents, pretty, pretty::write_mir_fn,
VarDebugInfoContents, pretty::MirWriter,
},
ty::{Region, Ty, TyCtxt},
};
Expand Down Expand Up @@ -118,15 +117,7 @@ impl<'tcx> BodyExt<'tcx> for Body<'tcx> {

fn to_string(&self, tcx: TyCtxt<'tcx>) -> Result<String> {
let mut buffer = Vec::new();
write_mir_fn(
tcx,
self,
&mut |_, _| Ok(()),
&mut buffer,
PrettyPrintMirOptions {
include_extra_comments: false,
},
)?;
MirWriter::new(tcx).write_mir_fn(self, &mut buffer)?;
Ok(String::from_utf8(buffer)?)
}

Expand Down
11 changes: 5 additions & 6 deletions crates/rustc_utils/src/mir/borrowck_facts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use rustc_borrowck::consumers::{BodyWithBorrowckFacts, ConsumerOptions};
use rustc_data_structures::fx::FxHashSet as HashSet;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::{
mir::{Body, ConcreteOpaqueTypes, StatementKind, TerminatorKind},
mir::{Body, StatementKind, TerminatorKind},
ty::TyCtxt,
util::Providers,
};
use rustc_span::ErrorGuaranteed;

use crate::{BodyExt, block_timer, cache::Cache};

Expand Down Expand Up @@ -61,7 +60,7 @@ pub fn enable_mir_simplification() {
/// For why we need to do override mir_borrowck, see:
/// <https://github.com/rust-lang/rust/blob/485ced56b8753ec86936903f2a8c95e9be8996a1/src/test/run-make-fulldeps/obtain-borrowck/driver.rs>
pub fn override_queries(_session: &rustc_session::Session, local: &mut Providers) {
local.mir_borrowck = mir_borrowck;
local.queries.mir_borrowck = mir_borrowck;
}

thread_local! {
Expand All @@ -71,7 +70,7 @@ thread_local! {
fn mir_borrowck(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
) -> Result<&ConcreteOpaqueTypes<'_>, ErrorGuaranteed> {
) -> rustc_middle::queries::mir_borrowck::ProvidedValue<'_> {
block_timer!(&format!(
"get_bodies_with_borrowck_facts for {}",
tcx.def_path_debug_str(def_id.to_def_id())
Expand All @@ -96,8 +95,8 @@ fn mir_borrowck(
});
}
let mut providers = Providers::default();
rustc_borrowck::provide(&mut providers);
let original_mir_borrowck = providers.mir_borrowck;
rustc_borrowck::provide(&mut providers.queries);
let original_mir_borrowck = providers.queries.mir_borrowck;
original_mir_borrowck(tcx, def_id)
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_utils/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl<'tcx> OperandExt<'tcx> for Operand<'tcx> {
fn as_place(&self) -> Option<Place<'tcx>> {
match self {
Operand::Copy(place) | Operand::Move(place) => Some(*place),
Operand::Constant(_) => None,
Operand::Constant(_) | Operand::RuntimeChecks(_) => None,
}
}
}
21 changes: 6 additions & 15 deletions crates/rustc_utils/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ use log::{trace, warn};
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_data_structures::fx::{FxHashMap as HashMap, FxHashSet as HashSet};
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::{
mir::{
Body, HasLocalDecls, Local, Location, Mutability, Place, PlaceElem, PlaceRef,
ProjectionElem, RETURN_PLACE, VarDebugInfo, VarDebugInfoContents,
visit::{PlaceContext, Visitor},
},
traits::ObligationCause,
ty::{self, AdtKind, Region, RegionKind, RegionVid, Ty, TyCtxt, TyKind, TypeVisitor},
};
use rustc_trait_selection::traits::NormalizeExt;
use rustc_type_ir::TypingMode;
use rustc_type_ir::Unnormalized;

use crate::{AdtDefExt, SpanExt};

Expand Down Expand Up @@ -285,7 +282,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
}
ProjectionElem::Downcast(sym, _) => {
let variant = sym.map(|s| s.to_string()).unwrap_or_else(|| "??".into());
(ElemPosition::Suffix, format!("@{variant}",).into())
(ElemPosition::Suffix, format!("@{variant}").into())
}

ProjectionElem::Index(_) => (ElemPosition::Suffix, "[_]".into()),
Expand Down Expand Up @@ -319,16 +316,10 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
}

fn normalize(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Place<'tcx> {
let param_env = tcx.param_env(def_id);
let place = tcx.erase_regions(*self);
let infcx = tcx.infer_ctxt().build(TypingMode::post_borrowck_analysis(
tcx,
def_id.expect_local(),
));
let place = infcx
.at(&ObligationCause::dummy(), param_env)
.normalize(place)
.value;
let place = tcx.normalize_erasing_regions(
tcx.typing_env_normalized_for_post_analysis(def_id),
Unnormalized::new_wip(*self),
);

let projection = place
.projection
Expand Down
38 changes: 32 additions & 6 deletions crates/rustc_utils/src/source_map/filename.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
use std::path::PathBuf;
use std::{fmt, path::PathBuf};

use rustc_index::Idx;

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Filename(pub PathBuf);

rustc_index::newtype_index! {
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[debug_format = "f{}"]
pub struct FilenameIndex {}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
pub struct FilenameIndex(usize);

impl fmt::Debug for FilenameIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "f{}", self.0)
}
}

impl Idx for FilenameIndex {
fn new(idx: usize) -> Self {
FilenameIndex(idx)
}

fn index(self) -> usize {
self.0
}
}

// NOTE(nightly-2026-05-01): the newtype_index has been commented out below
// bc it uses some wacky `T is range` type that isn't implemented by serde or ts_rs.

// rustc_index::newtype_index! {
// #[cfg_attr(feature = "serde", derive(serde::Serialize))]
// #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
// #[debug_format = "f{}"]
// pub struct FilenameIndex {}
// }
18 changes: 11 additions & 7 deletions crates/rustc_utils/src/source_map/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use rustc_hir::{
};
use rustc_index::IndexVec;
use rustc_middle::ty::TyCtxt;
use rustc_span::{FileName, RealFileName, SourceFile, Span, source_map::SourceMap};
use rustc_span::{
FileName, RemapPathScopeComponents, SourceFile, Span, source_map::SourceMap,
};
#[cfg(feature = "serde")]
use serde::Serialize;
#[cfg(feature = "ts-rs")]
Expand Down Expand Up @@ -141,9 +143,10 @@ impl FilenameIndex {
.find(|name| match &name {
// rustc seems to store relative paths to files in the workspace, so if filename is absolute,
// we can compare them using Path::ends_with
FileName::Real(RealFileName::LocalPath(other)) => {
FileName::Real(real_file_name) => {
let other = real_file_name.path(RemapPathScopeComponents::DOCUMENTATION).to_path_buf();
let canonical = other.canonicalize();
let other = canonical.as_ref().unwrap_or(other);
let other = canonical.as_ref().unwrap_or(&other);
filename.ends_with(other)
}
_ => false,
Expand All @@ -155,8 +158,8 @@ impl FilenameIndex {
files
.iter()
.filter_map(|file| match &file.name {
FileName::Real(RealFileName::LocalPath(other)) =>
Some(format!("{}", other.display())),
FileName::Real(other) =>
Some(other.path(RemapPathScopeComponents::DOCUMENTATION).display().to_string()),
_ => None,
})
.collect::<Vec<_>>()
Expand Down Expand Up @@ -269,8 +272,9 @@ impl ByteRange {
log::trace!("Converting to range: {span:?}");
let file = source_map.lookup_source_file(span.lo());
let filename = match &file.name {
FileName::Real(RealFileName::LocalPath(filename)) => {
Filename(filename.clone()).intern_with_ctx(&mut ctx)
FileName::Real(real_file_name) => {
let filename = real_file_name.path(RemapPathScopeComponents::DOCUMENTATION);
Filename(filename.to_path_buf()).intern_with_ctx(&mut ctx)
}
filename => bail!("Range::from_span doesn't support {filename:?}"),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_utils/src/source_map/spanner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_middle::{
},
ty::TyCtxt,
};
use rustc_span::{Span, SpanData, source_map::Spanned};
use rustc_span::{Span, SpanData, Spanned};

pub use self::hir_span::EnclosingHirSpans;
use self::{
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_utils/src/source_map/spanner/span_tree.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use intervaltree::IntervalTree;
use rustc_span::{BytePos, SpanData, source_map::Spanned};
use rustc_span::{BytePos, SpanData, Spanned};

/// Interval tree data structure specialized to spans.
pub struct SpanTree<T> {
Expand Down
4 changes: 4 additions & 0 deletions crates/rustc_utils/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ impl FileLoader for StringLoader {
fn read_binary_file(&self, path: &Path) -> io::Result<Arc<[u8]>> {
Ok(fs::read(path)?.into())
}

fn current_directory(&self) -> io::Result<std::path::PathBuf> {
Ok(std::env::current_dir().unwrap())
}
}

static SYSROOT: LazyLock<String> = LazyLock::new(|| {
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-08-20"
channel = "nightly-2026-05-01"
components = ["clippy", "rust-src", "rustc-dev", "llvm-tools-preview"]
Loading