Skip to content
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

Rollup of 4 pull requests #116902

Closed
wants to merge 8 commits into from
1 change: 1 addition & 0 deletions .mailmap
Expand Up @@ -74,6 +74,7 @@ Benoît Cortier <benoit.cortier@fried-world.eu>
Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
blyxyas <blyxyas@gmail.com> Alejandra González <blyxyas@gmail.com>
boolean_coercion <booleancoercion@gmail.com>
Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
bors <bors@rust-lang.org> bors[bot] <26634292+bors[bot]@users.noreply.github.com>
Expand Down
2 changes: 0 additions & 2 deletions Cargo.lock
Expand Up @@ -4482,9 +4482,7 @@ name = "rustc_smir"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
"rustc_driver",
"rustc_hir",
"rustc_interface",
"rustc_middle",
"rustc_span",
"rustc_target",
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint_defs/src/builtin.rs
Expand Up @@ -4449,11 +4449,11 @@ declare_lint! {
/// on itself), the blanket impl is not considered to hold for `u8`. This will
/// change in a future release.
pub COINDUCTIVE_OVERLAP_IN_COHERENCE,
Warn,
Deny,
"impls that are not considered to overlap may be considered to \
overlap in the future",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #114040 <https://github.com/rust-lang/rust/issues/114040>",
};
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Expand Up @@ -383,7 +383,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
let is_fn_like = tcx.def_kind(def).is_fn_like();
if is_fn_like {
// Do not compute the mir call graph without said call graph actually being used.
if inline::Inline.is_enabled(&tcx.sess) {
if pm::should_run_pass(tcx, &inline::Inline) {
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
}
}
Expand Down
33 changes: 21 additions & 12 deletions compiler/rustc_mir_transform/src/pass_manager.rs
Expand Up @@ -83,6 +83,25 @@ pub fn run_passes<'tcx>(
run_passes_inner(tcx, body, passes, phase_change, true);
}

pub fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
where
P: MirPass<'tcx> + ?Sized,
{
let name = pass.name();

let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
let overridden =
overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(|(_name, polarity)| {
trace!(
pass = %name,
"{} as requested by flag",
if *polarity { "Running" } else { "Not running" },
);
*polarity
});
overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess))
}

fn run_passes_inner<'tcx>(
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
Expand All @@ -100,19 +119,9 @@ fn run_passes_inner<'tcx>(
for pass in passes {
let name = pass.name();

let overridden = overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(
|(_name, polarity)| {
trace!(
pass = %name,
"{} as requested by flag",
if *polarity { "Running" } else { "Not running" },
);
*polarity
},
);
if !overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess)) {
if !should_run_pass(tcx, *pass) {
continue;
}
};

let dump_enabled = pass.is_mir_dump_enabled();

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_smir/Cargo.toml
Expand Up @@ -5,9 +5,7 @@ edition = "2021"

[dependencies]
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_driver = { path = "../rustc_driver" }
rustc_hir = { path = "../rustc_hir" }
rustc_interface = { path = "../rustc_interface" }
rustc_middle = { path = "../rustc_middle" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
Expand Down
130 changes: 72 additions & 58 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Expand Up @@ -3,22 +3,18 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.

use crate::rustc_internal;
use crate::rustc_smir::Tables;
use rustc_data_structures::fx;
use rustc_data_structures::fx::FxIndexMap;
use rustc_driver::{Callbacks, Compilation, RunCompiler};
use rustc_interface::{interface, Queries};
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::ty;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{CrateNum, DefId};
use rustc_span::Span;
use stable_mir::ty::IndexedVal;
use stable_mir::CompilerError;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{ControlFlow, Index};
use std::ops::Index;

impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
type Output = DefId;
Expand Down Expand Up @@ -141,63 +137,81 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
);
}

pub struct StableMir<B = (), C = ()>
where
B: Send,
C: Send,
{
args: Vec<String>,
callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
result: Option<ControlFlow<B, C>>,
}
#[macro_export]
macro_rules! run {
($args:expr, $callback:expr) => {
run!($args, tcx, $callback)
};
($args:expr, $tcx:ident, $callback:expr) => {{
use rustc_driver::{Callbacks, Compilation, RunCompiler};
use rustc_interface::{interface, Queries};
use stable_mir::CompilerError;
use std::ops::ControlFlow;

pub struct StableMir<B = (), C = ()>
where
B: Send,
C: Send,
{
args: Vec<String>,
callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
result: Option<ControlFlow<B, C>>,
}

impl<B, C> StableMir<B, C>
where
B: Send,
C: Send,
{
/// Creates a new `StableMir` instance, with given test_function and arguments.
pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
StableMir { args, callback, result: None }
}

/// Runs the compiler against given target and tests it with `test_function`
pub fn run(&mut self) -> Result<C, CompilerError<B>> {
let compiler_result =
rustc_driver::catch_fatal_errors(|| RunCompiler::new(&self.args.clone(), self).run());
match (compiler_result, self.result.take()) {
(Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
(Ok(Ok(())), Some(ControlFlow::Break(value))) => Err(CompilerError::Interrupted(value)),
(Ok(Ok(_)), None) => Err(CompilerError::Skipped),
(Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
(Err(_), _) => Err(CompilerError::ICE),
impl<B, C> StableMir<B, C>
where
B: Send,
C: Send,
{
/// Creates a new `StableMir` instance, with given test_function and arguments.
pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
StableMir { args, callback, result: None }
}

/// Runs the compiler against given target and tests it with `test_function`
pub fn run(&mut self) -> Result<C, CompilerError<B>> {
let compiler_result = rustc_driver::catch_fatal_errors(|| {
RunCompiler::new(&self.args.clone(), self).run()
});
match (compiler_result, self.result.take()) {
(Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
(Ok(Ok(())), Some(ControlFlow::Break(value))) => {
Err(CompilerError::Interrupted(value))
}
(Ok(Ok(_)), None) => Err(CompilerError::Skipped),
(Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
(Err(_), _) => Err(CompilerError::ICE),
}
}
}
}
}

impl<B, C> Callbacks for StableMir<B, C>
where
B: Send,
C: Send,
{
/// Called after analysis. Return value instructs the compiler whether to
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
fn after_analysis<'tcx>(
&mut self,
_compiler: &interface::Compiler,
queries: &'tcx Queries<'tcx>,
) -> Compilation {
queries.global_ctxt().unwrap().enter(|tcx| {
rustc_internal::run(tcx, || {
self.result = Some((self.callback)(tcx));
});
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
Compilation::Continue
} else {
Compilation::Stop
impl<B, C> Callbacks for StableMir<B, C>
where
B: Send,
C: Send,
{
/// Called after analysis. Return value instructs the compiler whether to
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
fn after_analysis<'tcx>(
&mut self,
_compiler: &interface::Compiler,
queries: &'tcx Queries<'tcx>,
) -> Compilation {
queries.global_ctxt().unwrap().enter(|tcx| {
rustc_internal::run(tcx, || {
self.result = Some((self.callback)(tcx));
});
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
Compilation::Continue
} else {
Compilation::Stop
}
})
}
})
}
}

StableMir::new($args, |$tcx| $callback).run()
}};
}

/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
Expand Down
19 changes: 19 additions & 0 deletions tests/mir-opt/inline/unit_test.rs
@@ -0,0 +1,19 @@
// Check that `-Zmir-enable-passes=+Inline` does not ICE because of stolen MIR.
// unit-test: Inline
// skip-filecheck
#![crate_type = "lib"]

// Randomize `def_path_hash` by defining them under a module with different names
macro_rules! emit {
($($m:ident)*) => {$(
pub mod $m {
pub fn main() {
let func = || 123u8;
func();
}
}
)*};
}

// Increase the chance of triggering the bug
emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);
18 changes: 9 additions & 9 deletions tests/ui-fulldeps/stable-mir/compilation-result.rs
Expand Up @@ -10,13 +10,15 @@
#![feature(assert_matches)]

extern crate rustc_middle;
#[macro_use]
extern crate rustc_smir;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate stable_mir;

use rustc_middle::ty::TyCtxt;
use rustc_smir::rustc_internal;
use std::io::Write;
use std::ops::ControlFlow;

/// This test will generate and analyze a dummy crate using the stable mir.
/// For that, it will first write the dummy crate into a file.
Expand All @@ -33,28 +35,26 @@ fn main() {
}

fn test_continue(args: Vec<String>) {
let continue_fn = |_: TyCtxt| ControlFlow::Continue::<(), bool>(true);
let result = rustc_internal::StableMir::new(args, continue_fn).run();
let result = run!(args, ControlFlow::Continue::<(), bool>(true));
assert_eq!(result, Ok(true));
}

fn test_break(args: Vec<String>) {
let continue_fn = |_: TyCtxt| ControlFlow::Break::<bool, i32>(false);
let result = rustc_internal::StableMir::new(args, continue_fn).run();
let result = run!(args, ControlFlow::Break::<bool, i32>(false));
assert_eq!(result, Err(stable_mir::CompilerError::Interrupted(false)));
}

#[allow(unreachable_code)]
fn test_skipped(mut args: Vec<String>) {
args.push("--version".to_string());
let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
let result = rustc_internal::StableMir::new(args, unreach_fn).run();
let result = run!(args, unreachable!() as ControlFlow<()>);
assert_eq!(result, Err(stable_mir::CompilerError::Skipped));
}

#[allow(unreachable_code)]
fn test_failed(mut args: Vec<String>) {
args.push("--cfg=broken".to_string());
let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
let result = rustc_internal::StableMir::new(args, unreach_fn).run();
let result = run!(args, unreachable!() as ControlFlow<()>);
assert_eq!(result, Err(stable_mir::CompilerError::CompilationFailed));
}

Expand Down
5 changes: 4 additions & 1 deletion tests/ui-fulldeps/stable-mir/crate-info.rs
Expand Up @@ -12,7 +12,10 @@

extern crate rustc_hir;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_smir;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate stable_mir;

use rustc_hir::def::DefKind;
Expand Down Expand Up @@ -185,7 +188,7 @@ fn main() {
CRATE_NAME.to_string(),
path.to_string(),
];
rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
run!(args, tcx, test_stable_mir(tcx)).unwrap();
}

fn generate_input(path: &str) -> std::io::Result<()> {
Expand Down
5 changes: 4 additions & 1 deletion tests/ui-fulldeps/stable-mir/instance.rs
Expand Up @@ -11,8 +11,11 @@
#![feature(control_flow_enum)]

extern crate rustc_middle;
#[macro_use]
extern crate rustc_smir;
extern crate stable_mir;
extern crate rustc_driver;
extern crate rustc_interface;

use rustc_middle::ty::TyCtxt;

Expand Down Expand Up @@ -61,7 +64,7 @@ fn main() {
CRATE_NAME.to_string(),
path.to_string(),
];
rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
run!(args, tcx, test_stable_mir(tcx)).unwrap();
}

fn generate_input(path: &str) -> std::io::Result<()> {
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
Expand Up @@ -24,3 +24,28 @@ LL | #![deny(coinductive_overlap_in_coherence)]

error: aborting due to previous error

Future incompatibility report: Future breakage diagnostic:
error: implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:13:1
|
LL | #[derive(PartialEq, Default)]
| --------- the second impl is here
...
LL | / impl<T, Q> PartialEq<Q> for Interval<T>
LL | |
LL | |
LL | | where
LL | | T: Borrow<Q>,
LL | | Q: ?Sized + PartialOrd,
| |___________________________^ the first impl is here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #114040 <https://github.com/rust-lang/rust/issues/114040>
= note: impls that are not considered to overlap may be considered to overlap in the future
= note: `Interval<_>: PartialOrd` may be considered to hold in future releases, causing the impls to overlap
note: the lint level is defined here
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:1:9
|
LL | #![deny(coinductive_overlap_in_coherence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^