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 #135448

Closed
wants to merge 9 commits into from
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ pub(super) fn take_opaques_and_register_member_constraints<'tcx>(
let opaque_types = infcx
.take_opaque_types()
.into_iter()
.map(|(opaque_type_key, decl)| {
let hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
.map(|(opaque_type_key, hidden_type)| {
let hidden_type = infcx.resolve_vars_if_possible(hidden_type);
register_member_constraints(
typeck,
&mut member_constraints,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,9 @@ fn check_opaque_meets_bounds<'tcx>(
} else {
// Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
for (mut key, mut ty) in infcx.take_opaque_types() {
ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
ty.ty = infcx.resolve_vars_if_possible(ty.ty);
key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
sanity_check_found_hidden_type(tcx, key, ty)?;
}
Ok(())
}
Expand Down Expand Up @@ -1873,7 +1873,7 @@ pub(super) fn check_coroutine_obligations(
// Check that any hidden types found when checking these stalled coroutine obligations
// are valid.
for (key, ty) in infcx.take_opaque_types() {
let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
let hidden_type = infcx.resolve_vars_if_possible(ty);
let key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, hidden_type)?;
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// types or by using this function at the end of writeback and running it as a
// fixpoint.
let opaque_types = self.fcx.infcx.clone_opaque_types();
for (opaque_type_key, decl) in opaque_types {
let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
for (opaque_type_key, hidden_type) in opaque_types {
let hidden_type = self.resolve(hidden_type, &hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);

if !self.fcx.next_trait_solver() {
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ impl<'tcx> InferCtxt<'tcx> {
.opaque_type_storage
.opaque_types
.iter()
.map(|(k, v)| (*k, v.hidden_type.ty))
.map(|(k, v)| (*k, v.ty))
.collect()
}

fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.take_opaque_types().into_iter().map(|(k, v)| (k, v.hidden_type.ty)).collect()
self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect()
}

/// Given the (canonicalized) result to a canonical query,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
pub fn iter_opaque_types(
&self,
) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> + '_ {
self.opaque_type_storage.opaque_types.iter().map(|(&k, v)| (k, v.hidden_type))
self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v))
}
}

Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_infer/src/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,9 @@ use crate::traits::{self, Obligation, PredicateObligations};

mod table;

pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>;
pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};

/// Information about the opaque types whose values we
/// are inferring in this function (these are the `impl Trait` that
/// appear in the return type).
#[derive(Clone, Debug)]
pub struct OpaqueTypeDecl<'tcx> {
/// The hidden types that have been inferred for this opaque type.
/// There can be multiple, but they are all `lub`ed together at the end
/// to obtain the canonical hidden type.
pub hidden_type: OpaqueHiddenType<'tcx>,
}

impl<'tcx> InferCtxt<'tcx> {
/// This is a backwards compatibility hack to prevent breaking changes from
/// lazy TAIT around RPIT handling.
Expand Down
21 changes: 12 additions & 9 deletions compiler/rustc_infer/src/infer/opaque_types/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@ use rustc_middle::bug;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use tracing::instrument;

use super::{OpaqueTypeDecl, OpaqueTypeMap};
use super::OpaqueTypeMap;
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};

#[derive(Default, Debug, Clone)]
pub(crate) struct OpaqueTypeStorage<'tcx> {
/// Opaque types found in explicit return types and their
/// associated fresh inference variable. Writeback resolves these
/// variables to get the concrete type, which can be used to
/// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
/// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
pub opaque_types: OpaqueTypeMap<'tcx>,
}

impl<'tcx> OpaqueTypeStorage<'tcx> {
#[instrument(level = "debug")]
pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
if let Some(idx) = idx {
self.opaque_types.get_mut(&key).unwrap().hidden_type = idx;
pub(crate) fn remove(
&mut self,
key: OpaqueTypeKey<'tcx>,
prev: Option<OpaqueHiddenType<'tcx>>,
) {
if let Some(prev) = prev {
*self.opaque_types.get_mut(&key).unwrap() = prev;
} else {
// FIXME(#120456) - is `swap_remove` correct?
match self.opaque_types.swap_remove(&key) {
Expand Down Expand Up @@ -59,13 +63,12 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
) -> Option<Ty<'tcx>> {
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(entry, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
return Some(prev.ty);
}
let decl = OpaqueTypeDecl { hidden_type };
self.storage.opaque_types.insert(key, decl);
self.storage.opaque_types.insert(key, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/impl_trait_overcaptures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ declare_lint! {
/// To fix this, remove the `use<'a>`, since the lifetime is already captured
/// since it is in scope.
pub IMPL_TRAIT_REDUNDANT_CAPTURES,
Warn,
Allow,
"redundant precise-capturing `use<...>` syntax on an `impl Trait`",
}

Expand Down
24 changes: 15 additions & 9 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1555,16 +1555,22 @@ pub fn write_allocations<'tcx>(
write!(w, " (vtable: impl {dyn_ty} for {ty})")?
}
Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
match tcx.eval_static_initializer(did) {
Ok(alloc) => {
write!(w, " (static: {}, ", tcx.def_path_str(did))?;
write_allocation_track_relocs(w, alloc)?;
write!(w, " (static: {}", tcx.def_path_str(did))?;
if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup)
&& tcx.hir().body_const_context(body.source.def_id()).is_some()
{
// Statics may be cyclic and evaluating them too early
// in the MIR pipeline may cause cycle errors even though
// normal compilation is fine.
write!(w, ")")?;
} else {
match tcx.eval_static_initializer(did) {
Ok(alloc) => {
write!(w, ", ")?;
write_allocation_track_relocs(w, alloc)?;
}
Err(_) => write!(w, ", error during initializer evaluation)")?,
}
Err(_) => write!(
w,
" (static: {}, error during initializer evaluation)",
tcx.def_path_str(did)
)?,
}
}
Some(GlobalAlloc::Static(did)) => {
Expand Down
47 changes: 30 additions & 17 deletions library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ macro_rules! rtunwrap {
};
}

fn handle_rt_panic(e: Box<dyn Any + Send>) {
fn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T {
mem::forget(e);
rtabort!("initialization or cleanup bug");
}
Expand Down Expand Up @@ -157,7 +157,7 @@ fn lang_start_internal(
argc: isize,
argv: *const *const u8,
sigpipe: u8,
) -> Result<isize, !> {
) -> isize {
// Guard against the code called by this function from unwinding outside of the Rust-controlled
// code, which is UB. This is a requirement imposed by a combination of how the
// `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
Expand All @@ -168,19 +168,33 @@ fn lang_start_internal(
// panic is a std implementation bug. A quite likely one too, as there isn't any way to
// prevent std from accidentally introducing a panic to these functions. Another is from
// user code from `main` or, more nefariously, as described in e.g. issue #86030.
// SAFETY: Only called once during runtime initialization.
panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) })
.unwrap_or_else(handle_rt_panic);
let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
.map_err(move |e| {
mem::forget(e);
rtabort!("drop of the panic payload panicked");
//
// We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in
// case of a panic a bit nicer.
panic::catch_unwind(move || {
// SAFETY: Only called once during runtime initialization.
unsafe { init(argc, argv, sigpipe) };

let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| {
// Carefully dispose of the panic payload.
let payload = panic::AssertUnwindSafe(payload);
panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| {
mem::forget(e); // do *not* drop the 2nd payload
rtabort!("drop of the panic payload panicked");
});
// Return error code for panicking programs.
101
});
panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic);
// Guard against multiple threads calling `libc::exit` concurrently.
// See the documentation for `unique_thread_exit` for more information.
panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic);
ret_code
let ret_code = ret_code as isize;

cleanup();
// Guard against multiple threads calling `libc::exit` concurrently.
// See the documentation for `unique_thread_exit` for more information.
crate::sys::exit_guard::unique_thread_exit();

ret_code
})
.unwrap_or_else(handle_rt_panic)
}

#[cfg(not(any(test, doctest)))]
Expand All @@ -191,11 +205,10 @@ fn lang_start<T: crate::process::Termination + 'static>(
argv: *const *const u8,
sigpipe: u8,
) -> isize {
let Ok(v) = lang_start_internal(
lang_start_internal(
&move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
argc,
argv,
sigpipe,
);
v
)
}
6 changes: 3 additions & 3 deletions src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
= note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#1}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
= note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#0}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
= note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#1})
RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0})
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
at RUSTLIB/std/src/panicking.rs:LL:CC
7: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
8: std::rt::lang_start_internal::{closure#1}
8: std::rt::lang_start_internal::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
9: std::panicking::r#try::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
at RUSTLIB/std/src/panicking.rs:LL:CC
11: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
12: std::rt::lang_start_internal::{closure#1}
12: std::rt::lang_start_internal::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
13: std::panicking::r#try::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
Expand Down
19 changes: 19 additions & 0 deletions tests/mir-opt/building/dump_mir_cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(Debug)]
pub struct Thing {
pub next: &'static Thing,
}

pub static THING: Thing = Thing { next: &THING };
// CHECK: alloc{{.+}} (static: THING)

const fn thing() -> &'static Thing {
&MUTUALLY_RECURSIVE
}

pub static MUTUALLY_RECURSIVE: Thing = Thing { next: thing() };
// CHECK: alloc{{.+}} (static: MUTUALLY_RECURSIVE)

fn main() {
// Generate optimized MIR for the const fn, too.
thing();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,4 @@ const BAR::promoted[0]: &[&i32; 1] = {
}
}

ALLOC0 (static: Y, size: 4, align: 4) {
2a 00 00 00 │ *...
}
ALLOC0 (static: Y)
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@
bb2 (cleanup): {
resume;
}
- }
-
- ALLOC0 (static: Y, size: 4, align: 4) {
- 2a 00 00 00 │ *...
}
-
- ALLOC0 (static: Y)

10 changes: 5 additions & 5 deletions tests/ui/impl-trait/precise-capturing/redundant.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
//@ edition: 2024
//@ check-pass

#![feature(precise_capturing_in_traits)]
#![deny(impl_trait_redundant_captures)]

fn hello<'a>() -> impl Sized + use<'a> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured

struct Inherent;
impl Inherent {
fn inherent(&self) -> impl Sized + use<'_> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}

trait Test<'a> {
fn in_trait() -> impl Sized + use<'a, Self>;
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}
impl<'a> Test<'a> for () {
fn in_trait() -> impl Sized + use<'a> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}

fn main() {}
Loading
Loading