Skip to content

Commit

Permalink
Auto merge of rust-lang#137212 - GuillaumeGomez:rollup-fc4rqfu, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 11 pull requests

Successful merges:

 - rust-lang#127793 (Added project-specific Zed IDE settings)
 - rust-lang#134995 (Stabilize const_slice_flatten)
 - rust-lang#135767 (Future incompatibility warning `unsupported_fn_ptr_calling_conventions`: Also warn in dependencies)
 - rust-lang#136599 (librustdoc: more usages of `Joined::joined`)
 - rust-lang#136750 (Make ub_check message clear that it's not an assert)
 - rust-lang#137000 (Deeply normalize item bounds in new solver)
 - rust-lang#137126 (fix docs for inherent str constructors)
 - rust-lang#137151 (Install more signal stack trace handlers)
 - rust-lang#137161 (Pattern Migration 2024: fix incorrect messages/suggestions when errors arise in macro expansions)
 - rust-lang#137167 (tests: Also gate `f16::erfc()` doctest with `reliable_f16_math` cfg)
 - rust-lang#137177 (Update `minifier-rs` version to `0.3.5`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 18, 2025
2 parents 3b022d8 + 2f3a29a commit a584f94
Show file tree
Hide file tree
Showing 43 changed files with 1,044 additions and 211 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2303,9 +2303,9 @@ dependencies = [

[[package]]
name = "minifier"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cf47565b1430f5fe6c81d3afcb4b835271348d7eb35294a4d592e38dd09ea22"
checksum = "9bfdc64e2f805f3d12965f10522000bae36e88d2cfea44112331f467d4f4bf68"

[[package]]
name = "minimal-lexical"
Expand Down
50 changes: 39 additions & 11 deletions compiler/rustc_driver_impl/src/signal_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ use std::{fmt, mem, ptr, slice};

use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE};

/// Signals that represent that we have a bug, and our prompt termination has
/// been ordered.
#[rustfmt::skip]
const KILL_SIGNALS: [(libc::c_int, &str); 3] = [
(libc::SIGILL, "SIGILL"),
(libc::SIGBUS, "SIGBUS"),
(libc::SIGSEGV, "SIGSEGV")
];

unsafe extern "C" {
fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int);
}
Expand Down Expand Up @@ -39,8 +48,19 @@ macro raw_errln($tokens:tt) {
/// # Safety
///
/// Caller must ensure that this function is not re-entered.
unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
unsafe extern "C" fn print_stack_trace(signum: libc::c_int) {
const MAX_FRAMES: usize = 256;

let signame = {
let mut signame = "<unknown>";
for sig in KILL_SIGNALS {
if sig.0 == signum {
signame = sig.1;
}
}
signame
};

let stack = unsafe {
// Reserve data segment so we don't have to malloc in a signal handler, which might fail
// in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking
Expand All @@ -54,7 +74,8 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
};

// Just a stack trace is cryptic. Explain what we're doing.
raw_errln!("error: rustc interrupted by SIGSEGV, printing backtrace\n");
raw_errln!("error: rustc interrupted by {signame}, printing backtrace\n");

let mut written = 1;
let mut consumed = 0;
// Begin elaborating return addrs into symbols and writing them directly to stderr
Expand Down Expand Up @@ -94,7 +115,7 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
written += rem.len() + 1;

let random_depth = || 8 * 16; // chosen by random diceroll (2d20)
if cyclic || stack.len() > random_depth() {
if (cyclic || stack.len() > random_depth()) && signum == libc::SIGSEGV {
// technically speculation, but assert it with confidence anyway.
// rustc only arrived in this signal handler because bad things happened
// and this message is for explaining it's not the programmer's fault
Expand All @@ -106,17 +127,22 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
written += 1;
}
raw_errln!("note: we would appreciate a report at https://github.com/rust-lang/rust");
// get the current stack size WITHOUT blocking and double it
let new_size = STACK_SIZE.get().copied().unwrap_or(DEFAULT_STACK_SIZE) * 2;
raw_errln!("help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}");
written += 2;
written += 1;
if signum == libc::SIGSEGV {
// get the current stack size WITHOUT blocking and double it
let new_size = STACK_SIZE.get().copied().unwrap_or(DEFAULT_STACK_SIZE) * 2;
raw_errln!(
"help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}"
);
written += 1;
}
if written > 24 {
// We probably just scrolled the earlier "we got SIGSEGV" message off the terminal
raw_errln!("note: backtrace dumped due to SIGSEGV! resuming signal");
// We probably just scrolled the earlier "interrupted by {signame}" message off the terminal
raw_errln!("note: backtrace dumped due to {signame}! resuming signal");
};
}

/// When SIGSEGV is delivered to the process, print a stack trace and then exit.
/// When one of the KILL signals is delivered to the process, print a stack trace and then exit.
pub(super) fn install() {
unsafe {
let alt_stack_size: usize = min_sigstack_size() + 64 * 1024;
Expand All @@ -129,7 +155,9 @@ pub(super) fn install() {
sa.sa_sigaction = print_stack_trace as libc::sighandler_t;
sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK;
libc::sigemptyset(&mut sa.sa_mask);
libc::sigaction(libc::SIGSEGV, &sa, ptr::null_mut());
for (signum, _signame) in KILL_SIGNALS {
libc::sigaction(signum, &sa, ptr::null_mut());
}
}
}

Expand Down
64 changes: 22 additions & 42 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2104,18 +2104,21 @@ pub(super) fn check_type_bounds<'tcx>(
ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
};

let mut obligations: Vec<_> = tcx
.explicit_item_bounds(trait_ty.def_id)
.iter_instantiated_copied(tcx, rebased_args)
.map(|(concrete_ty_bound, span)| {
debug!(?concrete_ty_bound);
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
})
.collect();
let mut obligations: Vec<_> = util::elaborate(
tcx,
tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map(
|(concrete_ty_bound, span)| {
debug!(?concrete_ty_bound);
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
},
),
)
.collect();

// Only in a const implementation do we need to check that the `~const` item bounds hold.
if tcx.is_conditionally_const(impl_ty_def_id) {
obligations.extend(
obligations.extend(util::elaborate(
tcx,
tcx.explicit_implied_const_bounds(trait_ty.def_id)
.iter_instantiated_copied(tcx, rebased_args)
.map(|(c, span)| {
Expand All @@ -2126,34 +2129,27 @@ pub(super) fn check_type_bounds<'tcx>(
c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
)
}),
);
));
}
debug!(item_bounds=?obligations);

// Normalize predicates with the assumption that the GAT may always normalize
// to its definition type. This should be the param-env we use to *prove* the
// predicate too, but we don't do that because of performance issues.
// See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args);
let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
for mut obligation in util::elaborate(tcx, obligations) {
let normalized_predicate = if infcx.next_trait_solver() {
obligation.predicate.fold_with(&mut ReplaceTy {
tcx,
from: trait_projection_ty,
to: impl_identity_ty,
})
} else {
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
};
debug!(?normalized_predicate);
obligation.predicate = normalized_predicate;

ocx.register_obligation(obligation);
for obligation in &mut obligations {
match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) {
Ok(pred) => obligation.predicate = pred,
Err(e) => {
return Err(infcx.err_ctxt().report_fulfillment_errors(e));
}
}
}

// Check that all obligations are satisfied by the implementation's
// version.
ocx.register_obligations(obligations);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
Expand All @@ -2165,22 +2161,6 @@ pub(super) fn check_type_bounds<'tcx>(
ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types)
}

struct ReplaceTy<'tcx> {
tcx: TyCtxt<'tcx>,
from: Ty<'tcx>,
to: Ty<'tcx>,
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
fn cx(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if self.from == ty { self.to } else { ty.super_fold_with(self) }
}
}

/// Install projection predicates that allow GATs to project to their own
/// definition types. This is not allowed in general in cases of default
/// associated types in trait definitions, or when specialization is involved,
Expand Down
34 changes: 18 additions & 16 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2806,31 +2806,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& !self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
});

let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
info.bad_modifiers = true;
// If the user-provided binding modifier doesn't match the default binding mode, we'll
// need to suggest reference patterns, which can affect other bindings.
// For simplicity, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes &=
user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
"binding modifier"
} else {
info.bad_ref_pats = true;
// For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
// suggest adding them instead, which can affect the types assigned to bindings.
// As such, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes = false;
"reference pattern"
};
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
let from_expansion = subpat.span.from_expansion();
let primary_label = if from_expansion {
// We can't suggest eliding modifiers within expansions.
info.suggest_eliding_modes = false;
// NB: This wording assumes the only expansions that can produce problematic reference
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
// so, we may want to inspect the span's source callee or macro backtrace.
"occurs within macro expansion".to_owned()
} else {
let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
info.bad_modifiers |= true;
// If the user-provided binding modifier doesn't match the default binding mode, we'll
// need to suggest reference patterns, which can affect other bindings.
// For simplicity, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes &=
user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
"binding modifier"
} else {
info.bad_ref_pats |= true;
// For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
// suggest adding them instead, which can affect the types assigned to bindings.
// As such, we opt to suggest making the pattern fully explicit.
info.suggest_eliding_modes = false;
"reference pattern"
};
let dbm_str = match def_br_mutbl {
Mutability::Not => "ref",
Mutability::Mut => "ref mut",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3782,7 +3782,7 @@ declare_lint! {
Warn,
"use of unsupported calling convention for function pointer",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
};
}
Expand Down
37 changes: 29 additions & 8 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ where
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Ambiguity));
};

let responses: Vec<_> = match proven_via {
match proven_via {
// Even when a trait bound has been proven using a where-bound, we
// still need to consider alias-bounds for normalization, see
// tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
Expand All @@ -800,7 +800,7 @@ where
// constness checking. Doing so is *at least theoretically* breaking,
// see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754
TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => {
let mut candidates_from_env: Vec<_> = candidates
let mut candidates_from_env_and_bounds: Vec<_> = candidates
.iter()
.filter(|c| {
matches!(
Expand All @@ -813,16 +813,37 @@ where

// If the trait goal has been proven by using the environment, we want to treat
// aliases as rigid if there are no applicable projection bounds in the environment.
if candidates_from_env.is_empty() {
if candidates_from_env_and_bounds.is_empty() {
if let Ok(response) = inject_normalize_to_rigid_candidate(self) {
candidates_from_env.push(response);
candidates_from_env_and_bounds.push(response);
}
}
candidates_from_env

if let Some(response) = self.try_merge_responses(&candidates_from_env_and_bounds) {
Ok(response)
} else {
self.flounder(&candidates_from_env_and_bounds)
}
}
TraitGoalProvenVia::Misc => candidates.iter().map(|c| c.result).collect(),
};
TraitGoalProvenVia::Misc => {
// Prefer "orphaned" param-env normalization predicates, which are used
// (for example, and ideally only) when proving item bounds for an impl.
let candidates_from_env: Vec<_> = candidates
.iter()
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
.map(|c| c.result)
.collect();
if let Some(response) = self.try_merge_responses(&candidates_from_env) {
return Ok(response);
}

self.try_merge_responses(&responses).map_or_else(|| self.flounder(&responses), Ok)
let responses: Vec<_> = candidates.iter().map(|c| c.result).collect();
if let Some(response) = self.try_merge_responses(&responses) {
Ok(response)
} else {
self.flounder(&responses)
}
}
}
}
}
4 changes: 2 additions & 2 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4796,7 +4796,7 @@ impl<T, const N: usize> [[T; N]] {
/// assert!(empty_slice_of_arrays.as_flattened().is_empty());
/// ```
#[stable(feature = "slice_flatten", since = "1.80.0")]
#[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
#[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
pub const fn as_flattened(&self) -> &[T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
Expand Down Expand Up @@ -4833,7 +4833,7 @@ impl<T, const N: usize> [[T; N]] {
/// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
/// ```
#[stable(feature = "slice_flatten", since = "1.80.0")]
#[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
#[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
pub const fn as_flattened_mut(&mut self) -> &mut [T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
Expand Down
Loading

0 comments on commit a584f94

Please sign in to comment.