Skip to content

Rollup of 9 pull requests #142181

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 25 commits into from
Jun 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
eec894d
Fix future-incompatible lint group test
Urgau May 1, 2025
80c6a08
Allow `#![doc(test(attr(..)))]` at module level too
Urgau May 1, 2025
9d9705f
Collect and use `#![doc(test(attr(..)))]` at module level too
Urgau May 1, 2025
041d95d
Allow `#![doc(test(attr(..)))]` doctests to be again merged together
Urgau May 1, 2025
316e62a
Allow `#![doc(test(attr(..)))]` at every level
Urgau May 5, 2025
d96d3be
Collect and use `#[doc(test(attr(..)))]` at every level
Urgau May 5, 2025
a08f6f1
document representation of `Option<unsafe fn()>`
y86-dev May 23, 2025
d851cfa
Make the `dangerous_implicit_autorefs` lint deny-by-default
Urgau May 27, 2025
53c1301
Stabilize `const_eq_ignore_ascii_case`
paolobarbolini Jun 5, 2025
46a936a
bootstrap: fix tracing imports
jieyouxu Jun 6, 2025
7efd90a
Treat normalizing consts like normalizing types in deeply normalize
compiler-errors Jun 6, 2025
aa1b296
Unify normalization of terms in deeply normalize
compiler-errors Jun 6, 2025
8aafcc8
compiler: Sort and doc ExternAbi variants
workingjubilee Jun 7, 2025
f66487b
compiler: Remove superfluous renaming import of ExternAbi
workingjubilee Jun 7, 2025
5bab0d2
compiler: Treat ForceWarning as a Warning for diagnostic level
workingjubilee Jun 7, 2025
6a6c595
get rid of spurious cfg(bootstrap)
RalfJung Jun 7, 2025
2c8a9cc
Rollup merge of #140560 - Urgau:test_attr-module-level, r=GuillaumeGomez
GuillaumeGomez Jun 7, 2025
00db345
Rollup merge of #141447 - y86-dev:option-layout-docs, r=RalfJung
GuillaumeGomez Jun 7, 2025
c475ad0
Rollup merge of #141661 - Urgau:deny-dangerous_implicit_autorefs, r=t…
GuillaumeGomez Jun 7, 2025
7b0eeab
Rollup merge of #142065 - paolobarbolini:stabilize-const_eq_ignore_as…
GuillaumeGomez Jun 7, 2025
215dc8c
Rollup merge of #142116 - jieyouxu:fix-tracing, r=Mark-Simulacrum
GuillaumeGomez Jun 7, 2025
7c3cb56
Rollup merge of #142126 - compiler-errors:normalize-uv-via-relate, r=…
GuillaumeGomez Jun 7, 2025
5f6d982
Rollup merge of #142140 - workingjubilee:sort-extern-abi-variants, r=…
GuillaumeGomez Jun 7, 2025
3c860e3
Rollup merge of #142148 - workingjubilee:dont-ice-on-force-warn, r=Urgau
GuillaumeGomez Jun 7, 2025
aa94060
Rollup merge of #142154 - RalfJung:no-more-cfg-bootstrap, r=oli-obk
GuillaumeGomez Jun 7, 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
99 changes: 63 additions & 36 deletions compiler/rustc_abi/src/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,93 @@ use crate::AbiFromStrErr;
#[cfg(test)]
mod tests;

use ExternAbi as Abi;

/// ABI we expect to see within `extern "{abi}"`
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable))]
pub enum ExternAbi {
// Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
// hashing tests. These are used in many places, so giving them stable values reduces test
// churn. The specific values are meaningless.
Rust,
/* universal */
/// presumed C ABI for the platform
C {
unwind: bool,
},
Cdecl {
/// ABI of the "system" interface, e.g. the Win32 API, always "aliasing"
System {
unwind: bool,
},
Stdcall {

/// that's us!
Rust,
/// the mostly-unused `unboxed_closures` ABI, effectively now an impl detail unless someone
/// puts in the work to make it viable again... but would we need a special ABI?
RustCall,
/// For things unlikely to be called, where reducing register pressure in
/// `extern "Rust"` callers is worth paying extra cost in the callee.
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
RustCold,

/// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM.
/// Even normally-compatible Rust types can become ABI-incompatible with this ABI!
Unadjusted,

/// UEFI ABI, usually an alias of C, but sometimes an arch-specific alias
/// and only valid on platforms that have a UEFI standard
EfiApi,

/* arm */
/// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
Aapcs {
unwind: bool,
},
Fastcall {
/// extremely constrained barely-C ABI for TrustZone
CCmseNonSecureCall,
/// extremely constrained barely-C ABI for TrustZone
CCmseNonSecureEntry,

/* gpu */
/// An entry-point function called by the GPU's host
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
GpuKernel,
/// An entry-point function called by the GPU's host
// FIXME: why do we have two of these?
PtxKernel,

/* interrupt */
AvrInterrupt,
AvrNonBlockingInterrupt,
Msp430Interrupt,
RiscvInterruptM,
RiscvInterruptS,
X86Interrupt,

/* x86 */
/// `ExternAbi::C` but spelled funny because x86
Cdecl {
unwind: bool,
},
Vectorcall {
/// gnu-stdcall on "unix" and win-stdcall on "windows"
Stdcall {
unwind: bool,
},
Thiscall {
/// gnu-fastcall on "unix" and win-fastcall on "windows"
Fastcall {
unwind: bool,
},
Aapcs {
/// windows C++ ABI
Thiscall {
unwind: bool,
},
Win64 {
/// uses AVX and stuff
Vectorcall {
unwind: bool,
},

/* x86_64 */
SysV64 {
unwind: bool,
},
PtxKernel,
Msp430Interrupt,
X86Interrupt,
/// An entry-point function called by the GPU's host
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
GpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
CCmseNonSecureCall,
CCmseNonSecureEntry,
System {
Win64 {
unwind: bool,
},
RustCall,
/// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
/// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
Unadjusted,
/// For things unlikely to be called, where reducing register pressure in
/// `extern "Rust"` callers is worth paying extra cost in the callee.
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
RustCold,
RiscvInterruptM,
RiscvInterruptS,
}

macro_rules! abi_impls {
Expand Down Expand Up @@ -224,7 +251,7 @@ pub fn all_names() -> Vec<&'static str> {

impl ExternAbi {
/// Default ABI chosen for `extern fn` declarations without an explicit ABI.
pub const FALLBACK: Abi = Abi::C { unwind: false };
pub const FALLBACK: ExternAbi = ExternAbi::C { unwind: false };

pub fn name(self) -> &'static str {
self.as_str()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ impl DiagCtxtInner {
// Future breakages aren't emitted if they're `Level::Allow` or
// `Level::Expect`, but they still need to be constructed and
// stashed below, so they'll trigger the must_produce_diag check.
assert_matches!(diagnostic.level, Error | Warning | Allow | Expect);
assert_matches!(diagnostic.level, Error | ForceWarning | Warning | Allow | Expect);
self.future_breakage_diagnostics.push(diagnostic.clone());
}

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> {
ty::Region::new_var(self.tcx, region_var)
}

pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> {
match term.kind() {
ty::TermKind::Ty(_) => self.next_ty_var(span).into(),
ty::TermKind::Const(_) => self.next_const_var(span).into(),
}
}

/// Return the universe that the region `r` was created in. For
/// most regions (e.g., `'static`, named regions from the user,
/// etc) this is the root universe U0. For inference variables or
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/autorefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ declare_lint! {
///
/// ### Example
///
/// ```rust
/// ```rust,compile_fail
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
/// unsafe { &raw mut (*ptr)[..16] }
/// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
Expand Down Expand Up @@ -51,7 +51,7 @@ declare_lint! {
/// }
/// ```
pub DANGEROUS_IMPLICIT_AUTOREFS,
Warn,
Deny,
"implicit reference to a dereference of a raw pointer",
report_in_external_macro
}
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,13 +1266,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
true
}

/// Checks that `doc(test(...))` attribute contains only valid attributes. Returns `true` if
/// valid.
fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
/// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place.
fn check_test_attr(&self, attr: &Attribute, meta: &MetaItemInner, hir_id: HirId) {
if let Some(metas) = meta.meta_item_list() {
for i_meta in metas {
match (i_meta.name(), i_meta.meta_item()) {
(Some(sym::attr | sym::no_crate_inject), _) => {}
(Some(sym::attr), _) => {
// Allowed everywhere like `#[doc]`
}
(Some(sym::no_crate_inject), _) => {
self.check_attr_crate_level(attr, meta, hir_id);
}
(_, Some(m)) => {
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
Expand Down Expand Up @@ -1359,9 +1363,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}

Some(sym::test) => {
if self.check_attr_crate_level(attr, meta, hir_id) {
self.check_test_attr(meta, hir_id);
}
self.check_test_attr(attr, meta, hir_id);
}

Some(
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
let infcx = self.goal.infcx;
match goal.predicate.kind().no_bound_vars() {
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
let unconstrained_term = match term.kind() {
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
};
let unconstrained_term = infcx.next_term_var_of_kind(term, span);
let goal =
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
Expand Down
91 changes: 25 additions & 66 deletions compiler/rustc_trait_selection/src/solve/normalize.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::assert_matches::assert_matches;
use std::fmt::Debug;

use rustc_data_structures::stack::ensure_sufficient_stack;
Expand All @@ -16,7 +15,6 @@ use tracing::instrument;
use super::{FulfillmentCtxt, NextSolverError};
use crate::error_reporting::InferCtxtErrorExt;
use crate::error_reporting::traits::OverflowCause;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError};

/// Deeply normalize all aliases in `value`. This does not handle inference and expects
Expand Down Expand Up @@ -97,19 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
{
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
assert_matches!(alias_ty.kind(), ty::Alias(..));

fn normalize_alias_term(
&mut self,
alias_term: ty::Term<'tcx>,
) -> Result<ty::Term<'tcx>, Vec<E>> {
let infcx = self.at.infcx;
let tcx = infcx.tcx;
let recursion_limit = tcx.recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let ty::Alias(_, data) = *alias_ty.kind() else {
unreachable!();
};
let term = alias_term.to_alias_term().unwrap();

self.at.infcx.err_ctxt().report_overflow_error(
OverflowCause::DeeplyNormalize(data.into()),
OverflowCause::DeeplyNormalize(term),
self.at.cause.span,
true,
|_| {},
Expand All @@ -118,14 +115,14 @@ where

self.depth += 1;

let new_infer_ty = infcx.next_ty_var(self.at.cause.span);
let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span);
let obligation = Obligation::new(
tcx,
self.at.cause.clone(),
self.at.param_env,
ty::PredicateKind::AliasRelate(
alias_ty.into(),
new_infer_ty.into(),
alias_term.into(),
infer_term.into(),
ty::AliasRelationDirection::Equate,
),
);
Expand All @@ -135,50 +132,13 @@ where

// Alias is guaranteed to be fully structurally resolved,
// so we can super fold here.
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
let result = ty.try_super_fold_with(self)?;
self.depth -= 1;
Ok(result)
}

fn normalize_unevaluated_const(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
) -> Result<ty::Const<'tcx>, Vec<E>> {
let infcx = self.at.infcx;
let tcx = infcx.tcx;
let recursion_limit = tcx.recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
self.at.infcx.err_ctxt().report_overflow_error(
OverflowCause::DeeplyNormalize(uv.into()),
self.at.cause.span,
true,
|_| {},
);
}

self.depth += 1;

let new_infer_ct = infcx.next_const_var(self.at.cause.span);
let obligation = Obligation::new(
tcx,
self.at.cause.clone(),
self.at.param_env,
ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() },
);

let result = if infcx.predicate_may_hold(&obligation) {
self.fulfill_cx.register_predicate_obligation(infcx, obligation);
let errors = self.fulfill_cx.select_where_possible(infcx);
if !errors.is_empty() {
return Err(errors);
}
let ct = infcx.resolve_vars_if_possible(new_infer_ct);
ct.try_fold_with(self)?
} else {
ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)?
let term = infcx.resolve_vars_if_possible(infer_term);
// super-folding the `term` will directly fold the `Ty` or `Const` so
// we have to match on the term and super-fold them manually.
let result = match term.kind() {
ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(),
ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(),
};

self.depth -= 1;
Ok(result)
}
Expand Down Expand Up @@ -238,7 +198,8 @@ where
if ty.has_escaping_bound_vars() {
let (ty, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
let result =
ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type();
Ok(PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
Expand All @@ -248,7 +209,7 @@ where
result,
))
} else {
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type())
}
}

Expand All @@ -260,15 +221,13 @@ where
return Ok(ct);
}

let uv = match ct.kind() {
ty::ConstKind::Unevaluated(ct) => ct,
_ => return ct.try_super_fold_with(self),
};
let ty::ConstKind::Unevaluated(..) = ct.kind() else { return ct.try_super_fold_with(self) };

if uv.has_escaping_bound_vars() {
let (uv, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv);
let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?;
if ct.has_escaping_bound_vars() {
let (ct, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct);
let result =
ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const();
Ok(PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
Expand All @@ -278,7 +237,7 @@ where
result,
))
} else {
ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> {
return Ok(term);
}

let new_infer = match term.kind() {
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
};
let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span);

// We simply emit an `alias-eq` goal here, since that will take care of
// normalizing the LHS of the projection until it is a rigid projection
Expand Down
Loading
Loading