From 5f456b20c90d60450a802f58015d1eb89d08b06c Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Thu, 17 Sep 2026 09:36:39 +0100 Subject: [PATCH 01/15] Move `Const` from `rustc_middle` to `rustc_type_ir` --- compiler/rustc_middle/src/ty/codec.rs | 13 - compiler/rustc_middle/src/ty/consts.rs | 246 ++---------------- compiler/rustc_middle/src/ty/context.rs | 26 +- .../src/ty/context/impl_interner.rs | 14 +- compiler/rustc_middle/src/ty/mod.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_middle/src/ty/relate.rs | 10 - .../rustc_middle/src/ty/structural_impls.rs | 88 +------ compiler/rustc_type_ir/src/inherent.rs | 70 ++--- compiler/rustc_type_ir/src/intern/mod.rs | 4 +- compiler/rustc_type_ir/src/interner.rs | 20 +- compiler/rustc_type_ir/src/ir_print.rs | 13 +- compiler/rustc_type_ir/src/serialize.rs | 20 +- compiler/rustc_type_ir/src/sty/consts.rs | 243 +++++++++++++++++ compiler/rustc_type_ir/src/sty/mod.rs | 3 + compiler/rustc_type_ir/src/ty_info.rs | 2 +- 16 files changed, 365 insertions(+), 414 deletions(-) create mode 100644 compiler/rustc_type_ir/src/sty/consts.rs diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 1a63c05e06ced..202698431275f 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -142,12 +142,6 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Clause<'tcx> { } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Const<'tcx> { - fn encode(&self, e: &mut E) { - self.0.0.encode(e); - } -} - impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Pattern<'tcx> { fn encode(&self, e: &mut E) { self.0.0.encode(e); @@ -292,13 +286,6 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::ParamEnv<'tcx> { } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Const<'tcx> { - fn decode(decoder: &mut D) -> Self { - let kind: ty::ConstKind<'tcx> = Decodable::decode(decoder); - decoder.interner().mk_ct_from_kind(kind) - } -} - impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Pattern<'tcx> { fn decode(decoder: &mut D) -> Self { decoder.interner().mk_pat(Decodable::decode(decoder)) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 9e9f8d5df45de..cbe7b6d732c0f 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,10 +1,7 @@ -use std::borrow::Cow; - -use rustc_data_structures::intern::Interned; -use rustc_macros::StableHash; -use rustc_span::{Span, bug}; +use rustc_macros::extension; +use rustc_span::bug; use rustc_type_ir::walk::TypeWalker; -use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; +use rustc_type_ir::{self as ir}; use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; @@ -17,204 +14,21 @@ mod valtree; pub use int::*; pub use kind::*; pub use lit::*; -use rustc_span::{DUMMY_SP, ErrorGuaranteed}; pub use valtree::*; pub type ConstKind<'tcx> = ir::ConstKind>; pub type AliasConst<'tcx> = ir::AliasConst>; pub type AliasConstKind<'tcx> = ir::AliasConstKind>; +pub type Const<'tcx> = ir::Const>; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); -#[derive(Copy, Clone, PartialEq, Eq, Hash, StableHash)] -#[rustc_pass_by_value] -pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo>>); - -impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> { - type Kind = ConstKind<'tcx>; - - fn kind(self) -> ConstKind<'tcx> { - self.kind() - } -} - -impl<'tcx> rustc_type_ir::Flags for Const<'tcx> { - fn flags(&self) -> TypeFlags { - self.0.flags - } - - fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex { - self.0.outer_exclusive_binder - } -} - -impl<'tcx> Const<'tcx> { - #[inline] - pub fn kind(self) -> ConstKind<'tcx> { - let a: &ConstKind<'tcx> = self.0.0; - *a - } - - #[inline] - pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>) -> Const<'tcx> { - tcx.mk_ct_from_kind(kind) - } - - #[inline] - pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Param(param)) - } - - #[inline] - pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer))) - } - - #[inline] - pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Fresh(fresh))) - } - - #[inline] - pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(infer)) - } - - #[inline] - pub fn new_bound( - tcx: TyCtxt<'tcx>, - debruijn: ty::DebruijnIndex, - bound_const: ty::BoundConst<'tcx>, - ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const)) - } - - #[inline] - pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Const<'tcx> { - Const::new( - tcx, - ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, ty::BoundConst::new(var)), - ) - } - - #[inline] - pub fn new_placeholder( - tcx: TyCtxt<'tcx>, - placeholder: ty::PlaceholderConst<'tcx>, - ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Placeholder(placeholder)) - } - - #[inline] - pub fn new_alias( - tcx: TyCtxt<'tcx>, - is_rigid: ty::IsRigid, - alias_const: ty::AliasConst<'tcx>, - ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Alias(is_rigid, alias_const)) - } - - #[inline] - pub fn new_value(tcx: TyCtxt<'tcx>, valtree: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Value(ty::Value { ty, valtree })) - } - - #[inline] - pub fn new_expr(tcx: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Expr(expr)) - } - - #[inline] - pub fn new_error(tcx: TyCtxt<'tcx>, e: ty::ErrorGuaranteed) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Error(e)) - } - - /// Like [Ty::new_error] but for constants. - #[track_caller] - pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Const<'tcx> { - Const::new_error_with_message( - tcx, - DUMMY_SP, - "ty::ConstKind::Error constructed but no error reported", - ) - } - - /// Like [Ty::new_error_with_message] but for constants. - #[track_caller] - pub fn new_error_with_message( - tcx: TyCtxt<'tcx>, - span: Span, - msg: impl Into>, - ) -> Const<'tcx> { - let reported = tcx.dcx().span_delayed_bug(span, msg); - Const::new_error(tcx, reported) - } - - pub fn is_trivially_wf(self) -> bool { - match self.kind() { - ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Bound(..) => { - true - } - ty::ConstKind::Infer(_) - | ty::ConstKind::Alias(..) - | ty::ConstKind::Value(_) - | ty::ConstKind::Error(_) - | ty::ConstKind::Expr(_) => false, - } - } -} - -impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> { - fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self { - Const::new_infer(tcx, infer) - } - - fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid) -> Self { - Const::new_var(tcx, vid) - } - - fn new_bound( - interner: TyCtxt<'tcx>, - debruijn: ty::DebruijnIndex, - bound_const: ty::BoundConst<'tcx>, - ) -> Self { - Const::new_bound(interner, debruijn, bound_const) - } - - fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self { - Const::new_bound(tcx, debruijn, ty::BoundConst::new(var)) - } - - fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self { - Const::new_canonical_bound(tcx, var) - } - - fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst<'tcx>) -> Self { - Const::new_placeholder(tcx, placeholder) - } - - fn new_alias( - interner: TyCtxt<'tcx>, - is_rigid: ty::IsRigid, - alias_const: ty::AliasConst<'tcx>, - ) -> Self { - Const::new_alias(interner, is_rigid, alias_const) - } - - fn new_expr(interner: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Self { - Const::new_expr(interner, expr) - } - - fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { - Const::new_error(interner, guar) - } -} - +#[extension(pub trait ConstExt<'tcx>)] impl<'tcx> Const<'tcx> { /// Creates a constant with the given integer value and interns it. #[inline] - pub fn from_bits( + fn from_bits( tcx: TyCtxt<'tcx>, bits: u128, typing_env: ty::TypingEnv<'tcx>, @@ -224,33 +38,36 @@ impl<'tcx> Const<'tcx> { .layout_of(typing_env.as_query_input(ty)) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) .size; - ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int(tcx, ScalarInt::try_from_uint(bits, size).unwrap()), - ty, - ) + let valtree = + ty::ValTree::from_scalar_int(tcx, ScalarInt::try_from_uint(bits, size).unwrap()); + ty::Const::new_value(tcx, valtree, ty) } #[inline] /// Creates an interned zst constant. - pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { + fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { ty::Const::new_value(tcx, ty::ValTree::zst(tcx), ty) } + #[inline] + fn new_value(tcx: TyCtxt<'tcx>, valtree: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Value(ty::Value { ty, valtree })) + } + #[inline] /// Creates an interned bool constant. - pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { + fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { Self::from_bits(tcx, v as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.bool) } #[inline] /// Creates an interned usize constant. - pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { + fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize) } /// Panics if `self.kind != ty::ConstKind::Value`. - pub fn to_value(self) -> ty::Value<'tcx> { + fn to_value(self) -> ty::Value<'tcx> { match self.kind() { ty::ConstKind::Value(cv) => cv, _ => bug!("expected ConstKind::Value, got {:?}", self.kind()), @@ -260,7 +77,7 @@ impl<'tcx> Const<'tcx> { /// Attempts to convert to a value. /// /// Note that this does not normalize the constant. - pub fn try_to_value(self) -> Option> { + fn try_to_value(self) -> Option> { match self.kind() { ty::ConstKind::Value(cv) => Some(cv), _ => None, @@ -272,7 +89,7 @@ impl<'tcx> Const<'tcx> { /// /// Note that this does not normalize the constant. #[inline] - pub fn to_leaf(self) -> ScalarInt { + fn to_leaf(self) -> ScalarInt { self.to_value().to_leaf() } @@ -281,28 +98,28 @@ impl<'tcx> Const<'tcx> { /// /// Note that this does not normalize the constant. #[inline] - pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] { + fn to_branch(self) -> &'tcx [ty::Const<'tcx>] { self.to_value().to_branch() } /// Attempts to convert to a `ValTreeKind::Leaf` value. /// /// Note that this does not normalize the constant. - pub fn try_to_leaf(self) -> Option { + fn try_to_leaf(self) -> Option { self.try_to_value()?.try_to_leaf() } /// Attempts to convert to a `ValTreeKind::Leaf` value. /// /// Note that this does not normalize the constant. - pub fn try_to_scalar(self) -> Option { + fn try_to_scalar(self) -> Option { self.try_to_leaf().map(Scalar::Int) } /// Attempts to convert to a `ValTreeKind::Branch` value. /// /// Note that this does not normalize the constant. - pub fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> { + fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> { self.try_to_value()?.try_to_branch() } @@ -311,21 +128,10 @@ impl<'tcx> Const<'tcx> { /// /// Note that this does not evaluate the constant. #[inline] - pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { self.try_to_value()?.try_to_target_usize(tcx) } - pub fn is_ct_infer(self) -> bool { - matches!(self.kind(), ty::ConstKind::Infer(_)) - } - - pub fn ct_vid(self) -> Option { - match self.kind() { - ConstKind::Infer(ty::InferConst::Var(vid)) => Some(vid), - _ => None, - } - } - /// Iterator that walks `self` and any types reachable from /// `self`, in depth-first order. Note that just walks the types /// that appear in `self`, it does not descend into the fields of @@ -336,7 +142,7 @@ impl<'tcx> Const<'tcx> { /// Foo> => { Foo>, Bar, isize } /// [isize] => { [isize], isize } /// ``` - pub fn walk(self) -> TypeWalker> { + fn walk(self) -> TypeWalker> { TypeWalker::new(self.into()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9d0b334b63fbd..fdfa05048e936 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -69,11 +69,11 @@ use crate::traits::solve::{ }; use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ - self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, FnSigKind, - GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, - ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, - PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, - ValTreeKind, Visibility, + self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, ConstKind, + FnSigKind, GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List, + ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, + Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, + TyVid, ValTree, ValTreeKind, Visibility, }; impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { @@ -1711,7 +1711,6 @@ macro_rules! nop_list_lift { } nop_lift! { type_; Ty<'a> => Ty<'tcx> } -nop_lift! { const_; Const<'a> => Const<'tcx> } nop_lift! { pat; Pattern<'a> => Pattern<'tcx> } nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> } nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> } @@ -1731,6 +1730,21 @@ impl<'a, 'tcx> Lift> for Interned<'a, RegionKind<'a>> { } } +// `rustc_type_ir::Const` is only the generic wrapper; lifting it delegates +// to `I::InternedConstKind`, so the concrete interned const representation +// must itself implement `Lift`. +impl<'a, 'tcx> Lift> for Interned<'a, WithCachedTypeInfo>> { + type Lifted = Interned<'tcx, WithCachedTypeInfo>>; + + #[track_caller] + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted { + assert!(tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0))); + // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so + // its pointee is valid for the entire lifetime of the target `TyCtxt`. + unsafe { mem::transmute(self) } + } +} + nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> } nop_list_lift! { clauses: ListWithCachedTypeInfo; Clause<'a> => Clause<'tcx> } nop_list_lift! { diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 0cb926ec1c108..65b79018696e9 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -13,7 +13,7 @@ use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, Sol use rustc_type_ir::solve::CanonicalInputData; use rustc_type_ir::{ BoundVar, CollectAndApply, DebruijnIndex, Interner, RegionVid, TypeFoldable, Unnormalized, - VisitorResult, search_graph, try_visit, + VisitorResult, WithCachedTypeInfo, search_graph, try_visit, }; use crate::dep_graph::{DepKind, DepNodeIndex}; @@ -109,8 +109,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Pat = Pattern<'tcx>; type PatList = &'tcx List>; type Safety = hir::Safety; - type Const = ty::Const<'tcx>; - type Consts = &'tcx List; + type Consts = &'tcx List>; type ParamConst = ty::ParamConst; type ValueConst = ty::Value<'tcx>; @@ -118,6 +117,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ValTree = ty::ValTree<'tcx>; type ScalarInt = ty::ScalarInt; type InternedRegionKind = Interned<'tcx, ty::RegionKind<'tcx>>; + type InternedConstKind = Interned<'tcx, WithCachedTypeInfo>>; type EarlyParamRegion = ty::EarlyParamRegion; type LateParamRegionKind = ty::LateParamRegionKind; @@ -357,6 +357,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.mk_type_list_from_iter(args) } + fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> ty::Const<'tcx> { + self.mk_ct_from_kind(kind) + } + fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId { self.parent(def_id) } @@ -794,9 +798,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } -impl<'tcx, T: std::fmt::Debug + Clone + Copy> rustc_type_ir::intern::Interned> - for Interned<'tcx, T> -{ +impl<'tcx, T: Clone + Copy> rustc_type_ir::intern::Interned> for Interned<'tcx, T> { type Value = T; fn get(self) -> T { *self.0 diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e23ce6b246f12..9f110184aaede 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -124,6 +124,8 @@ pub mod abstract_const; pub mod adjustment; pub mod cast; pub mod codec; +// FIXME(#159654): This should get deleted soon +pub mod consts; pub mod error; pub mod fast_reject; pub mod inhabitedness; @@ -143,7 +145,6 @@ pub mod vtable; mod adt; mod assoc; mod closure; -mod consts; mod context; mod diagnostics; mod elaborate_impl; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1da8071ce69ce..52777974db785 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -24,6 +24,7 @@ use smallvec::SmallVec; use super::*; use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::query::{IntoQueryKey, Providers}; +use crate::ty::consts::ConstExt; use crate::ty::{ ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitClause, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -3143,8 +3144,7 @@ macro_rules! define_print_and_forward_display { forward_display_to_print! { Ty<'tcx>, - &'tcx ty::List>, - ty::Const<'tcx> + &'tcx ty::List> } define_print! { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index abbfd0f279a93..477e5133cc358 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -98,16 +98,6 @@ impl<'tcx> Relate> for ty::GenericArgsRef<'tcx> { } } -impl<'tcx> Relate> for ty::Const<'tcx> { - fn relate>>( - relation: &mut R, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, - ) -> RelateResult<'tcx, ty::Const<'tcx>> { - relation.consts(a, b) - } -} - impl<'tcx> Relate> for ty::Expr<'tcx> { fn relate>>( relation: &mut R, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 0ea7e403ee111..02107fee370cb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -9,7 +9,7 @@ use rustc_abi::TyAndLayout; use rustc_hir::def::Namespace; use rustc_hir::def_id::LocalDefId; use rustc_span::Spanned; -use rustc_type_ir::{ConstKind, PredicateProxy, TypeFolder, Upcast, VisitorResult, try_visit}; +use rustc_type_ir::{PredicateProxy, TypeFolder, Upcast, VisitorResult, try_visit}; use super::{GenericArg, GenericArgKind, Pattern}; use crate::mir::PlaceElem; @@ -141,18 +141,6 @@ impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> { } } -impl<'tcx> fmt::Debug for ty::Const<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // If this is a value, we spend some effort to make it look nice. - if let ConstKind::Value(cv) = self.kind() { - write!(f, "{}", cv) - } else { - // Fall back to something verbose. - write!(f, "{:?}", self.kind()) - } - } -} - impl<'tcx> fmt::Debug for GenericArg<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind() { @@ -651,80 +639,6 @@ impl<'tcx> TypeSuperFoldable> for ty::Clauses<'tcx> { } } -impl<'tcx> TypeFoldable> for ty::Const<'tcx> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - folder.try_fold_const(self) - } - - fn fold_with>>(self, folder: &mut F) -> Self { - folder.fold_const(self) - } -} - -impl<'tcx> TypeVisitable> for ty::Const<'tcx> { - fn visit_with>>(&self, visitor: &mut V) -> V::Result { - visitor.visit_const(*self) - } -} - -impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { - fn try_super_fold_with>>( - self, - folder: &mut F, - ) -> Result { - let kind = match self.kind() { - ConstKind::Alias(is_rigid, alias_const) => { - ConstKind::Alias(is_rigid, alias_const.try_fold_with(folder)?) - } - ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?), - ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?), - - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(..) - | ConstKind::Placeholder(_) - | ConstKind::Error(_) => return Ok(self), - }; - if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) } - } - - fn super_fold_with>>(self, folder: &mut F) -> Self { - let kind = match self.kind() { - ConstKind::Alias(is_rigid, alias_const) => { - ConstKind::Alias(is_rigid, alias_const.fold_with(folder)) - } - ConstKind::Value(v) => ConstKind::Value(v.fold_with(folder)), - ConstKind::Expr(e) => ConstKind::Expr(e.fold_with(folder)), - - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(..) - | ConstKind::Placeholder(_) - | ConstKind::Error(_) => return self, - }; - if kind != self.kind() { folder.cx().mk_ct_from_kind(kind) } else { self } - } -} - -impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { - fn super_visit_with>>(&self, visitor: &mut V) -> V::Result { - match self.kind() { - ConstKind::Alias(_, alias_const) => alias_const.visit_with(visitor), - ConstKind::Value(v) => v.visit_with(visitor), - ConstKind::Expr(e) => e.visit_with(visitor), - ConstKind::Error(e) => e.visit_with(visitor), - - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(..) - | ConstKind::Placeholder(_) => V::Result::output(), - } - } -} - impl<'tcx> TypeVisitable> for ty::ValTree<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { let inner: &ty::ValTreeKind> = &*self; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index bf90ef707c051..26d094817ba09 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -14,7 +14,8 @@ use crate::relate::Relate; use crate::solve::{AdtDestructorKind, SizedTraitKind}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ - self as ty, ClauseKind, CollectAndApply, FieldInfo, Interner, PredicateKind, Region, UpcastFrom, + self as ty, ClauseKind, CollectAndApply, Const, FieldInfo, Interner, PredicateKind, Region, + UpcastFrom, }; #[rust_analyzer::prefer_underscore_import] @@ -111,7 +112,7 @@ pub trait Ty>: fn new_ref(interner: I, region: Region, ty: Self, mutbl: Mutability) -> Self; - fn new_array_with_const_len(interner: I, ty: Self, len: I::Const) -> Self; + fn new_array_with_const_len(interner: I, ty: Self, len: Const) -> Self; fn new_slice(interner: I, ty: Self) -> Self; @@ -228,50 +229,6 @@ pub trait Safety>: Copy + Debug + Hash + Eq { fn prefix_str(self) -> &'static str; } -pub trait Const>: - Copy - + Debug - + Hash - + Eq - + Into - + Into - + IntoKind> - + TypeSuperVisitable - + TypeSuperFoldable - + Relate - + Flags -{ - fn new_infer(interner: I, var: ty::InferConst) -> Self; - - fn new_var(interner: I, var: ty::ConstVid) -> Self; - - fn new_bound(interner: I, debruijn: ty::DebruijnIndex, bound_const: ty::BoundConst) -> Self; - - fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self; - - fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self; - - fn new_placeholder(interner: I, param: ty::PlaceholderConst) -> Self; - - fn new_alias(interner: I, is_rigid: ty::IsRigid, alias_const: ty::AliasConst) -> Self; - - fn new_expr(interner: I, expr: I::ExprConst) -> Self; - - fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self; - - fn new_error_with_message(interner: I, msg: impl ToString) -> Self { - Self::new_error(interner, interner.delay_bug(msg)) - } - - fn is_ct_var(self) -> bool { - matches!(self.kind(), ty::ConstKind::Infer(ty::InferConst::Var(_))) - } - - fn is_ct_error(self) -> bool { - matches!(self.kind(), ty::ConstKind::Error(_)) - } -} - #[rust_analyzer::prefer_underscore_import] pub trait ValueConst>: Copy + Debug + Hash + Eq { fn ty(self) -> I::Ty; @@ -300,7 +257,7 @@ pub trait GenericArg>: + Relate + From + From> - + From + + From> + From { fn as_term(&self) -> Option { @@ -319,11 +276,11 @@ pub trait GenericArg>: self.as_type().expect("expected a type") } - fn as_const(&self) -> Option { + fn as_const(&self) -> Option> { if let ty::GenericArgKind::Const(c) = self.kind() { Some(c) } else { None } } - fn expect_const(&self) -> I::Const { + fn expect_const(&self) -> Const { self.as_const().expect("expected a const") } @@ -346,7 +303,14 @@ pub trait GenericArg>: #[rust_analyzer::prefer_underscore_import] pub trait Term>: - Copy + Debug + Hash + Eq + IntoKind> + TypeFoldable + Relate + Copy + + Debug + + Hash + + Eq + + IntoKind> + + TypeFoldable + + Relate + + From> { fn as_type(&self) -> Option { if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None } @@ -356,11 +320,11 @@ pub trait Term>: self.as_type().expect("expected a type, but found a const") } - fn as_const(&self) -> Option { + fn as_const(&self) -> Option> { if let ty::TermKind::Const(c) = self.kind() { Some(c) } else { None } } - fn expect_const(&self) -> I::Const { + fn expect_const(&self) -> Const { self.as_const().expect("expected a const, but found a type") } @@ -420,7 +384,7 @@ pub trait GenericArgs>: fn region_at(self, i: usize) -> Region; - fn const_at(self, i: usize) -> I::Const; + fn const_at(self, i: usize) -> Const; fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs; diff --git a/compiler/rustc_type_ir/src/intern/mod.rs b/compiler/rustc_type_ir/src/intern/mod.rs index a4cdd85fe175b..88634b3829fe2 100644 --- a/compiler/rustc_type_ir/src/intern/mod.rs +++ b/compiler/rustc_type_ir/src/intern/mod.rs @@ -1,8 +1,6 @@ use std::hash::Hash; -use crate::fmt::Debug; - -pub trait Interned: Copy + Debug + Hash + Eq + PartialEq { +pub trait Interned: Copy + Hash + Eq + PartialEq { type Value; fn get(self) -> Self::Value; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 31a027c15fd01..a81b8289ac067 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -1,5 +1,5 @@ use std::borrow::Borrow; -use std::fmt::Debug; +use std::fmt::{Debug, Display}; use std::hash::Hash; use std::ops::Deref; @@ -21,8 +21,8 @@ use crate::solve::{ }; use crate::visit::{Flags, TypeVisitable}; use crate::{ - self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, DebruijnIndex, - Region, RegionKind, RegionVid, TraitRef, search_graph, + self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, Const, ConstKind, + DebruijnIndex, Region, RegionKind, RegionVid, TraitRef, WithCachedTypeInfo, search_graph, }; /// The central trait in the shared abstraction layer, specifying all implementation-specific @@ -177,7 +177,7 @@ pub trait Interner: type Symbol: Symbol; // Things stored inside of tys - type ErrorGuaranteed: Copy + Debug + Hash + Eq; + type ErrorGuaranteed: Copy + Debug + Hash + Eq + TypeVisitable; type BoundExistentialPredicates: BoundExistentialPredicates; type AllocId: Copy + Debug + Hash + Eq; type Pat: Copy @@ -198,10 +198,9 @@ pub trait Interner: type Safety: Safety; // Kinds of consts - type Const: Const; - type Consts: Copy + Debug + Hash + Eq + SliceLike + Default; + type Consts: Copy + Debug + Hash + Eq + SliceLike> + Default; type ParamConst: Copy + Debug + Hash + Eq + ParamLike; - type ValueConst: ValueConst; + type ValueConst: ValueConst + TypeFoldable + Display; type ExprConst: ExprConst; type ValTree: Copy + Debug + Hash + Eq + IntoKind>; type ScalarInt: Copy + Debug + Hash + Eq; @@ -238,6 +237,7 @@ pub trait Interner: + RegionName; type InternedRegionKind: Interned>; + type InternedConstKind: Interned>>; type RegionAssumptions: Copy + Debug @@ -285,7 +285,7 @@ pub trait Interner: fn const_of_item( self, alias: ty::AliasConstKind, - ) -> Option>; + ) -> Option>>; fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; fn def_span(self, def_id: Self::DefId) -> Self::Span; @@ -341,6 +341,8 @@ pub trait Interner: I: Iterator, T: CollectAndApply; + fn mk_ct_from_kind(self, kind: ConstKind) -> Const; + fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId; /// This can be an impl, or a trait if this is a defaulted term. @@ -585,7 +587,6 @@ macro_rules! declare_lift_into { declare_lift_into! { BoundVarKinds, - Const, DefId, EarlyParamRegion, ErrorGuaranteed, @@ -595,6 +596,7 @@ declare_lift_into! { GenericArgs, InherentAssocConstId, InherentAssocTyId, + InternedConstKind, InternedRegionKind, OpaqueTyId, ParamEnv, diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 8133862e1bf1a..1f588a64bd80d 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -3,8 +3,8 @@ use std::fmt; #[cfg(feature = "nightly")] use crate::{AliasConst, ClosureKind}; use crate::{ - AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig, - HostEffectClause, Interner, NormalizesTo, OutlivesClause, PatternKind, Placeholder, + AliasTerm, AliasTy, Binder, CoercePredicate, Const, ExistentialProjection, ExistentialTraitRef, + FnSig, HostEffectClause, Interner, NormalizesTo, OutlivesClause, PatternKind, Placeholder, ProjectionClause, Region, SubtypePredicate, TraitClause, TraitRef, }; @@ -64,6 +64,15 @@ where } } +impl fmt::Display for Const +where + I: IrPrint>, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + >>::print(self, fmt) + } +} + impl fmt::Display for OutlivesClause where I: IrPrint>, diff --git a/compiler/rustc_type_ir/src/serialize.rs b/compiler/rustc_type_ir/src/serialize.rs index 835383b101136..eae1d05b7e8e7 100644 --- a/compiler/rustc_type_ir/src/serialize.rs +++ b/compiler/rustc_type_ir/src/serialize.rs @@ -2,7 +2,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use crate::inherent::*; use crate::visit::TypeVisitable; -use crate::{self as ty, Interner, Region, RegionKind, UnsafeBinderInner}; +use crate::{self as ty, Const, ConstKind, Interner, Region, RegionKind, UnsafeBinderInner}; /// A decoder that can reconstruct interned type IR values by supplying the /// interner that owns the decoded data. @@ -117,3 +117,21 @@ where decoder.interner().intern_region(Decodable::decode(decoder)) } } + +impl Encodable for Const +where + ConstKind: Encodable, +{ + fn encode(&self, e: &mut E) { + self.kind().encode(e); + } +} + +impl> Decodable for Const +where + ConstKind: Decodable, +{ + fn decode(decoder: &mut D) -> Self { + Const::new(decoder.interner(), Decodable::decode(decoder)) + } +} diff --git a/compiler/rustc_type_ir/src/sty/consts.rs b/compiler/rustc_type_ir/src/sty/consts.rs new file mode 100644 index 0000000000000..da2256078efa7 --- /dev/null +++ b/compiler/rustc_type_ir/src/sty/consts.rs @@ -0,0 +1,243 @@ +use std::fmt; + +use derive_where::derive_where; +use rustc_ast_ir::visit::VisitorResult; +#[cfg(feature = "nightly")] +use rustc_macros::StableHash_NoContext; +use rustc_type_ir_macros::{GenericTypeVisitable, Lift_Generic}; + +use crate::inherent::*; +use crate::intern::Interned; +use crate::relate::{Relate, RelateResult, TypeRelation}; +use crate::{ + AliasConst, BoundConst, BoundVar, BoundVarIndexKind, ConstKind, ConstVid, DebruijnIndex, + FallibleTypeFolder, Flags, InferConst, Interner, IsRigid, PlaceholderConst, TypeFlags, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, +}; + +#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)] +#[cfg_attr(feature = "nightly", derive(StableHash_NoContext))] +#[cfg_attr(feature = "nightly", rustc_pass_by_value)] +#[derive(GenericTypeVisitable, Lift_Generic)] +pub struct Const(pub I::InternedConstKind); + +impl fmt::Debug for Const { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // If this is a value, we spend some effort to make it look nice. + if let ConstKind::Value(cv) = self.kind() { + write!(f, "{}", cv) + } else { + // Fall back to something verbose. + write!(f, "{:?}", self.kind()) + } + } +} + +impl Const { + #[inline] + pub fn kind(self) -> ConstKind { + *self.0.get() + } + + #[inline] + pub fn new(interner: I, kind: ConstKind) -> Self { + interner.mk_ct_from_kind(kind) + } + + #[inline] + pub fn new_var(interner: I, infer: ConstVid) -> Self { + Self::new(interner, ConstKind::Infer(InferConst::Var(infer))) + } + + #[inline] + pub fn new_infer(interner: I, infer: InferConst) -> Self { + Self::new(interner, ConstKind::Infer(infer)) + } + + #[inline] + pub fn new_bound(interner: I, debruijn: DebruijnIndex, bound_const: BoundConst) -> Self { + Self::new(interner, ConstKind::Bound(BoundVarIndexKind::Bound(debruijn), bound_const)) + } + + #[inline] + pub fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self { + Self::new_bound(interner, debruijn, BoundConst::new(var)) + } + + #[inline] + pub fn new_canonical_bound(interner: I, var: BoundVar) -> Self { + Self::new(interner, ConstKind::Bound(BoundVarIndexKind::Canonical, BoundConst::new(var))) + } + + #[inline] + pub fn new_placeholder(interner: I, placeholder: PlaceholderConst) -> Self { + Self::new(interner, ConstKind::Placeholder(placeholder)) + } + + #[inline] + pub fn new_alias(interner: I, is_rigid: IsRigid, alias_const: AliasConst) -> Self { + Self::new(interner, ConstKind::Alias(is_rigid, alias_const)) + } + + #[inline] + pub fn new_expr(interner: I, expr: I::ExprConst) -> Self { + Const::new(interner, ConstKind::Expr(expr)) + } + + #[inline] + pub fn new_error(interner: I, e: I::ErrorGuaranteed) -> Self { + Const::new(interner, ConstKind::Error(e)) + } + + #[inline] + pub fn is_ct_var(self) -> bool { + matches!(self.kind(), ConstKind::Infer(InferConst::Var(_))) + } + + #[inline] + pub fn is_ct_error(self) -> bool { + matches!(self.kind(), ConstKind::Error(_)) + } + + #[inline] + pub fn new_param(interner: I, param: I::ParamConst) -> Self { + Self::new(interner, ConstKind::Param(param)) + } + + #[inline] + pub fn new_fresh(interner: I, fresh: u32) -> Self { + Self::new(interner, ConstKind::Infer(InferConst::Fresh(fresh))) + } + + #[track_caller] + pub fn new_misc_error(interner: I) -> Self { + Self::new_error_with_message( + interner, + I::Span::dummy(), + "ty::ConstKind::Error constructed but no error reported", + ) + } + + #[track_caller] + pub fn new_error_with_message(interner: I, span: I::Span, msg: impl ToString) -> Self { + let reported = interner.span_delayed_bug(span, msg); + Self::new_error(interner, reported) + } + + pub fn is_trivially_wf(self) -> bool { + match self.kind() { + ConstKind::Param(_) | ConstKind::Placeholder(_) | ConstKind::Bound(..) => true, + ConstKind::Infer(_) + | ConstKind::Alias(..) + | ConstKind::Value(_) + | ConstKind::Error(_) + | ConstKind::Expr(_) => false, + } + } + + pub fn is_ct_infer(self) -> bool { + matches!(self.kind(), ConstKind::Infer(_)) + } + + pub fn ct_vid(self) -> Option { + match self.kind() { + ConstKind::Infer(InferConst::Var(vid)) => Some(vid), + _ => None, + } + } +} + +impl Flags for Const { + fn flags(&self) -> TypeFlags { + self.0.get().flags + } + + fn outer_exclusive_binder(&self) -> DebruijnIndex { + self.0.get().outer_exclusive_binder + } +} + +impl IntoKind for Const { + type Kind = ConstKind; + + fn kind(self) -> Self::Kind { + *self.0.get() + } +} + +impl TypeFoldable for Const { + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_const(self) + } + + fn fold_with>(self, folder: &mut F) -> Self { + folder.fold_const(self) + } +} + +impl TypeVisitable for Const { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + visitor.visit_const(*self) + } +} + +impl TypeSuperFoldable for Const { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + let kind = match self.kind() { + ConstKind::Alias(is_rigid, alias_const) => { + ConstKind::Alias(is_rigid, alias_const.try_fold_with(folder)?) + } + ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?), + ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?), + + ConstKind::Param(_) + | ConstKind::Infer(_) + | ConstKind::Bound(..) + | ConstKind::Placeholder(_) + | ConstKind::Error(_) => return Ok(self), + }; + if kind != self.kind() { Ok(Self::new(folder.cx(), kind)) } else { Ok(self) } + } + + fn super_fold_with>(self, folder: &mut F) -> Self { + let kind = match self.kind() { + ConstKind::Alias(is_rigid, alias_const) => { + ConstKind::Alias(is_rigid, alias_const.fold_with(folder)) + } + ConstKind::Value(v) => ConstKind::Value(v.fold_with(folder)), + ConstKind::Expr(e) => ConstKind::Expr(e.fold_with(folder)), + + ConstKind::Param(_) + | ConstKind::Infer(_) + | ConstKind::Bound(..) + | ConstKind::Placeholder(_) + | ConstKind::Error(_) => return self, + }; + if kind != self.kind() { Self::new(folder.cx(), kind) } else { self } + } +} + +impl TypeSuperVisitable for Const { + fn super_visit_with>(&self, visitor: &mut V) -> V::Result { + match self.kind() { + ConstKind::Alias(_, alias_const) => alias_const.visit_with(visitor), + ConstKind::Value(v) => v.visit_with(visitor), + ConstKind::Expr(e) => e.visit_with(visitor), + ConstKind::Error(e) => e.visit_with(visitor), + + ConstKind::Param(_) + | ConstKind::Infer(_) + | ConstKind::Bound(..) + | ConstKind::Placeholder(_) => V::Result::output(), + } + } +} + +impl Relate for Const { + fn relate>(relation: &mut R, a: Self, b: Self) -> RelateResult { + relation.consts(a, b) + } +} diff --git a/compiler/rustc_type_ir/src/sty/mod.rs b/compiler/rustc_type_ir/src/sty/mod.rs index 0dfdda6af16cc..d513dd88faae6 100644 --- a/compiler/rustc_type_ir/src/sty/mod.rs +++ b/compiler/rustc_type_ir/src/sty/mod.rs @@ -1,3 +1,6 @@ +pub use consts::*; +mod consts; + use std::fmt; use derive_where::derive_where; diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs index 7aa34183a7a38..1a0975c657e9b 100644 --- a/compiler/rustc_type_ir/src/ty_info.rs +++ b/compiler/rustc_type_ir/src/ty_info.rs @@ -11,7 +11,7 @@ use crate::{DebruijnIndex, TypeFlags}; /// A helper type that you can wrap round your own type in order to automatically /// cache the type flags and debruijn index on creation and not recompute it /// whenever the information is needed. -#[derive(Copy, Clone, GenericTypeVisitable)] +#[derive(Copy, Clone, Debug, GenericTypeVisitable)] pub struct WithCachedTypeInfo { pub internee: T, From 9125d04fafa09fb1afad42295c40af9794e91ee2 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Thu, 17 Sep 2026 09:36:40 +0100 Subject: [PATCH 02/15] Remap `I::Const` -> `Const` --- .../src/canonical/canonicalizer.rs | 6 +++--- .../src/canonical/mod.rs | 6 +++--- .../rustc_next_trait_solver/src/coherence.rs | 4 ++-- .../rustc_next_trait_solver/src/delegate.rs | 6 +++--- .../rustc_next_trait_solver/src/normalize.rs | 6 +++--- .../src/placeholder.rs | 9 +++++---- .../src/solve/assembly/mod.rs | 4 ++-- .../src/solve/eval_ctxt/mod.rs | 12 +++++------ .../eval_ctxt/solver_region_constraints.rs | 6 +++--- .../rustc_next_trait_solver/src/solve/mod.rs | 10 +++++----- .../src/solve/normalizes_to.rs | 3 ++- compiler/rustc_type_ir/src/binder.rs | 12 +++++------ compiler/rustc_type_ir/src/canonical.rs | 2 +- compiler/rustc_type_ir/src/error.rs | 8 ++++---- compiler/rustc_type_ir/src/fast_reject.rs | 4 ++-- compiler/rustc_type_ir/src/flags.rs | 4 ++-- compiler/rustc_type_ir/src/fold.rs | 20 +++++++++---------- compiler/rustc_type_ir/src/generic_arg.rs | 4 ++-- compiler/rustc_type_ir/src/infer_ctxt.rs | 17 +++++++--------- compiler/rustc_type_ir/src/pattern.rs | 4 ++-- compiler/rustc_type_ir/src/predicate_kind.rs | 8 ++++---- .../rustc_type_ir/src/region_constraint.rs | 4 +++- compiler/rustc_type_ir/src/relate.rs | 10 +++++----- compiler/rustc_type_ir/src/relate/combine.rs | 8 ++++---- .../src/relate/solver_relating.rs | 4 ++-- compiler/rustc_type_ir/src/solve/mod.rs | 6 +++--- compiler/rustc_type_ir/src/term_kind.rs | 6 +++--- compiler/rustc_type_ir/src/ty_kind.rs | 4 ++-- compiler/rustc_type_ir/src/universe.rs | 4 ++-- compiler/rustc_type_ir/src/visit.rs | 8 ++++---- 30 files changed, 105 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index f0f0ebaf2b3bb..75c7513758cd0 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -5,8 +5,8 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::solve::{Goal, QueryInput}; use rustc_type_ir::{ self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalVarKind, CanonicalizerState, - Flags, InferCtxtLike, Interner, PlaceholderConst, PlaceholderType, PredicateProxy, Region, - TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + Const, Flags, InferCtxtLike, Interner, PlaceholderConst, PlaceholderType, PredicateProxy, + Region, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use thin_vec::ThinVec; @@ -525,7 +525,7 @@ impl, I: Interner> TypeFolder for Canonicaliz } } - fn fold_const(&mut self, c: I::Const) -> I::Const { + fn fold_const(&mut self, c: Const) -> Const { if !c.flags().intersects(NEEDS_CANONICAL) { return c; } diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index fc9024333bf44..45ae4cadf519c 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -18,8 +18,8 @@ use rustc_type_ir::relate::{ self, Relate, RelateResult, TypeRelation, VarianceDiagInfo, relate_args_invariantly, }; use rustc_type_ir::{ - self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Region, - TypeFoldable, TypingMode, TypingModeEqWrapper, + self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, Const, InferCtxtLike, Interner, + Region, TypeFoldable, TypingMode, TypingModeEqWrapper, }; use thin_vec::ThinVec; use tracing::instrument; @@ -421,7 +421,7 @@ where } #[instrument(skip(self), level = "trace")] - fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult { + fn consts(&mut self, a: Const, b: Const) -> RelateResult> { if a == b { return Ok(a); } diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index e37e69a617bbd..ad6fc98601f69 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -5,7 +5,7 @@ use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverAdtLangItem; use rustc_type_ir::{ - self as ty, InferCtxtLike, Interner, Region, TrivialTypeTraversalImpls, TypeVisitable, + self as ty, Const, InferCtxtLike, Interner, Region, TrivialTypeTraversalImpls, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use tracing::instrument; @@ -469,7 +469,7 @@ where /// As these should be quite rare as const arguments and especially rare as impl /// parameters, allowing uncovered const parameters in impls seems more useful /// than allowing `impl Trait for i32` to compile. - fn visit_const(&mut self, _c: I::Const) -> Self::Result { + fn visit_const(&mut self, _c: Const) -> Self::Result { ControlFlow::Continue(()) } } diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 0a307f766ebb2..24e321fc68c67 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -5,7 +5,7 @@ use rustc_type_ir::solve::{ Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck, }; -use rustc_type_ir::{self as ty, CanonicalizerState, InferCtxtLike, Interner, TypeFoldable}; +use rustc_type_ir::{self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TypeFoldable}; /// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer /// between rustc and rust-analyzer abstracting over the [InferCtxt][inferctxt-doc], which had to be @@ -63,7 +63,7 @@ pub trait SolverDelegate: Deref + Sized { normalize_ty: impl FnOnce( ty::Unnormalized::Ty>, ) -> Result<::Ty, E>, - ) -> Result::Const>, E>; + ) -> Result>, E>; // FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`! fn well_formed_goals( @@ -112,7 +112,7 @@ pub trait SolverDelegate: Deref + Sized { &self, src: ::Ty, dst: ::Ty, - assume: ::Const, + assume: Const, ) -> Result; /// Obtain canonicalizer state, either by allocating it afresh (the default) or by reusing diff --git a/compiler/rustc_next_trait_solver/src/normalize.rs b/compiler/rustc_next_trait_solver/src/normalize.rs index ab3a92da4ba54..c7d8d2919089b 100644 --- a/compiler/rustc_next_trait_solver/src/normalize.rs +++ b/compiler/rustc_next_trait_solver/src/normalize.rs @@ -2,8 +2,8 @@ use std::fmt::Debug; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, AliasTerm, Binder, FallibleTypeFolder, InferCtxtLike, Interner, PredicateProxy, - TypeFoldable, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, + self as ty, AliasTerm, Binder, Const, FallibleTypeFolder, InferCtxtLike, Interner, + PredicateProxy, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, }; use tracing::instrument; @@ -147,7 +147,7 @@ where } #[instrument(level = "trace", skip(self), ret)] - fn try_fold_const(&mut self, ct: I::Const) -> Result { + fn try_fold_const(&mut self, ct: Const) -> Result, Self::Error> { let infcx = self.infcx; let original = ct; diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index 84811a101fb11..c96aa90a10792 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -3,8 +3,9 @@ use core::panic; use rustc_type_ir::data_structures::IndexMap; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, InferCtxtLike, Interner, PlaceholderConst, PlaceholderRegion, PlaceholderType, - PredicateProxy, Region, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self as ty, Const, InferCtxtLike, Interner, PlaceholderConst, PlaceholderRegion, + PlaceholderType, PredicateProxy, Region, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, }; use tracing::debug; @@ -160,7 +161,7 @@ where } } - fn fold_const(&mut self, ct: I::Const) -> I::Const { + fn fold_const(&mut self, ct: Const) -> Const { match ct.kind() { ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) if debruijn.as_usize() + 1 @@ -310,7 +311,7 @@ where } } - fn fold_const(&mut self, ct: I::Const) -> I::Const { + fn fold_const(&mut self, ct: Const) -> Const { let ct = self.infcx.shallow_resolve_const(ct); if let ty::ConstKind::Placeholder(p) = ct.kind() { let replace_var = self.mapped_consts.get(&p); diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 485568850bee0..32e38ad88c856 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -14,7 +14,7 @@ use rustc_type_ir::solve::{ RerunNonErased, RerunReason, RerunResultExt, SizedTraitKind, StalledOnCoroutines, }; use rustc_type_ir::{ - self as ty, AliasTy, Interner, MayBeErased, Region, TypeFlags, TypeFoldable, TypeFolder, + self as ty, AliasTy, Const, Interner, MayBeErased, Region, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, Upcast, elaborate, }; @@ -1466,7 +1466,7 @@ where } } - fn visit_const(&mut self, ct: I::Const) -> Self::Result { + fn visit_const(&mut self, ct: Const) -> Self::Result { let ct = self.ecx.replace_bound_vars(ct, &mut self.universes); let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else { return ControlFlow::Break(Err(NoSolution)); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 3a4875c1d0951..52eaa445d68a6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_type_ir::solve::{ RerunNonErased, RerunReason, RerunResultExt, SmallCopySet, TyOrConstInferVar, }; use rustc_type_ir::{ - self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased, + self as ty, CanonicalVarValues, ClauseKind, Const, InferCtxtLike, Interner, MayBeErased, OpaqueTypeKey, PredicateKind, PredicateProxy, Region, RegionVid, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, max_universe, }; @@ -1057,7 +1057,7 @@ where ty } - pub(super) fn next_const_infer(&mut self) -> I::Const { + pub(super) fn next_const_infer(&mut self) -> Const { let ct = self.delegate.next_const_infer(); self.inspect.add_var_value(ct); ct @@ -1154,7 +1154,7 @@ where ControlFlow::Continue(()) } - fn visit_const(&mut self, c: I::Const) -> Self::Result { + fn visit_const(&mut self, c: Const) -> Self::Result { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { if let ty::TermKind::Const(term) = self.term.kind() @@ -1409,7 +1409,7 @@ where &mut self, param_env: I::ParamEnv, alias_const: ty::AliasConst, - ) -> Result, NoSolutionOrRerunNonErased> { + ) -> Result>, NoSolutionOrRerunNonErased> { if self.typing_mode().is_erased_not_coherence() { match self.opaque_accesses.rerun_always(RerunReason::EvaluateConst)? {} } @@ -1470,7 +1470,7 @@ where &mut self, src: I::Ty, dst: I::Ty, - assume: I::Const, + assume: Const, ) -> Result { self.delegate.is_transmutable(dst, src, assume) } @@ -1760,7 +1760,7 @@ fn filter_irrelevant_region_constraints( } t.super_visit_with(self); } - fn visit_const(&mut self, c: I::Const) { + fn visit_const(&mut self, c: Const) { // The same goes for consts. if !c.has_infer_regions() { return; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs index 5ecc06b30f33b..10dd8585b09c4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs @@ -11,8 +11,8 @@ use rustc_type_ir::region_constraint::{ propagate_ambiguity, }; use rustc_type_ir::{ - AliasTy, Binder, ClauseKind, InferCtxtLike, Interner, Region, TypeVisitable, TypeVisitableExt, - TypeVisitor, UniverseIndex, + AliasTy, Binder, ClauseKind, Const, InferCtxtLike, Interner, Region, TypeVisitable, + TypeVisitableExt, TypeVisitor, UniverseIndex, }; use tracing::{debug, instrument}; @@ -63,7 +63,7 @@ where ); } - fn visit_const(&mut self, c: I::Const) { + fn visit_const(&mut self, c: Const) { self.out.extend( self.ecx .well_formed_goals(self.param_env, c.into()) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 10ee038005d8e..1d7d2dd75c316 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -23,7 +23,7 @@ mod trait_goals; use derive_where::derive_where; use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Interner, Region, TypeVisitableExt}; +use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt}; use tracing::instrument; pub use self::eval_ctxt::{ @@ -205,7 +205,7 @@ where #[instrument(level = "trace", skip(self))] fn compute_const_evaluatable_goal( &mut self, - Goal { param_env, predicate: ct }: Goal, + Goal { param_env, predicate: ct }: Goal>, ) -> QueryResultOrRerunNonErased { match ct.kind() { ty::ConstKind::Alias(ty::IsRigid::Yes, _) @@ -248,7 +248,7 @@ where #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, - goal: Goal, + goal: Goal, I::Ty)>, ) -> QueryResultOrRerunNonErased { let (ct, ty) = goal.predicate; let ct = self.structurally_normalize_const(goal.param_env, ct)?; @@ -375,8 +375,8 @@ where fn structurally_normalize_const( &mut self, param_env: I::ParamEnv, - ct: I::Const, - ) -> Result { + ct: Const, + ) -> Result, NoSolutionOrRerunNonErased> { self.structurally_normalize_term(param_env, ct.into()).map(|term| term.expect_const()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index cb878f2c54878..388b334ccf618 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -8,7 +8,8 @@ use rustc_type_ir::solve::{ RerunNonErased, RerunReason, RerunResultExt, }; use rustc_type_ir::{ - self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Region, Unnormalized, Upcast as _, + self as ty, Const, FieldInfo, Interner, NormalizesTo, PredicateKind, Region, Unnormalized, + Upcast as _, }; use tracing::instrument; diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index a16610a520406..6722adfe24d5d 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -16,7 +16,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::{ - self as ty, DebruijnIndex, Interner, PredicateProxy, Region, UniverseIndex, Unnormalized, + self as ty, Const, DebruijnIndex, Interner, PredicateProxy, Region, UniverseIndex, Unnormalized, }; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the @@ -262,7 +262,7 @@ impl TypeVisitor for ValidateBoundVars { t.super_visit_with(self) } - fn visit_const(&mut self, c: I::Const) -> Self::Result { + fn visit_const(&mut self, c: Const) -> Self::Result { if c.outer_exclusive_binder() < self.binder_index { return ControlFlow::Break(()); } @@ -741,7 +741,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } } - fn fold_const(&mut self, c: I::Const) -> I::Const { + fn fold_const(&mut self, c: Const) -> Const { if let ty::ConstKind::Param(p) = c.kind() { self.const_for_param(p, c) } else { @@ -796,7 +796,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { ) } - fn const_for_param(&self, p: I::ParamConst, source_ct: I::Const) -> I::Const { + fn const_for_param(&self, p: I::ParamConst, source_ct: Const) -> Const { // Look up the const in the args. It really should be in there. let opt_ct = self.args.get(p.index() as usize).map(|arg| arg.kind()); let ct = match opt_ct { @@ -813,7 +813,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { fn const_param_expected( &self, p: I::ParamConst, - ct: I::Const, + ct: Const, kind: ty::GenericArgKind, ) -> ! { panic!( @@ -828,7 +828,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { #[cold] #[inline(never)] - fn const_param_out_of_range(&self, p: I::ParamConst, ct: I::Const) -> ! { + fn const_param_out_of_range(&self, p: I::ParamConst, ct: Const) -> ! { panic!( "const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}", p, diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index bba271ba13033..66ee34693c118 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -12,7 +12,7 @@ use thin_vec::ThinVec; use crate::data_structures::{DelayedMap, HashMap}; use crate::inherent::*; -use crate::{self as ty, Interner, Region, TypingModeEqWrapper, UniverseIndex}; +use crate::{self as ty, Const, Interner, Region, TypingModeEqWrapper, UniverseIndex}; #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, V)] #[derive_where(Copy; I: Interner, V: Copy)] diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index 59ceb4bd1e327..76b86d21b6ae4 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -3,7 +3,7 @@ use rustc_abi::ExternAbi; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::{NoSolution, NoSolutionOrRerunNonErased}; -use crate::{self as ty, Interner, Region}; +use crate::{self as ty, Const, Interner, Region}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)] @@ -30,7 +30,7 @@ pub enum TypeError { Mutability, ArgumentMutability(usize), TupleSize(ExpectedFound), - ArraySize(ExpectedFound), + ArraySize(ExpectedFound>), ArgCount, RegionsDoesNotOutlive(Region, Region), @@ -47,10 +47,10 @@ pub enum TypeError { /// created a cycle (because it appears somewhere within that /// type). CyclicTy(I::Ty), - CyclicConst(I::Const), + CyclicConst(Const), ProjectionMismatched(ExpectedFound>), ExistentialMismatch(ExpectedFound), - ConstMismatch(ExpectedFound), + ConstMismatch(ExpectedFound>), IntrinsicCast, /// `#[rustc_force_inline]` functions must be inlined and must not be codegened independently, diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index e9339338a6ef1..398fddcd4a141 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -9,7 +9,7 @@ use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash}; use crate::inherent::*; use crate::visit::TypeVisitableExt as _; -use crate::{self as ty, Interner}; +use crate::{self as ty, Const, Interner}; /// See `simplify_type`. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -486,7 +486,7 @@ impl bool { + fn consts_may_unify_inner(self, lhs: Const, rhs: Const) -> bool { match rhs.kind() { ty::ConstKind::Param(_) => { if INSTANTIATE_RHS_WITH_INFER { diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 7b0a098ad1948..4af4f1479ec82 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -1,6 +1,6 @@ use crate::inherent::*; use crate::visit::Flags; -use crate::{self as ty, Interner, Region}; +use crate::{self as ty, Const, Interner, Region}; bitflags::bitflags! { /// Flags that we track on types. These flags are propagated upwards @@ -463,7 +463,7 @@ impl FlagComputation { } } - fn add_const(&mut self, c: I::Const) { + fn add_const(&mut self, c: Const) { self.add_flags(c.flags()); self.add_exclusive_binder(c.outer_exclusive_binder()); } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 2b25de4132e62..388796732c2cb 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -56,8 +56,8 @@ use tracing::{debug, instrument}; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; use crate::{ - self as ty, Binder, BoundVarIndexKind, ClauseKind, Flags, Interner, ProjectionClause, Region, - TypeSuperVisitable, + self as ty, Binder, BoundVarIndexKind, ClauseKind, Const, Flags, Interner, ProjectionClause, + Region, TypeSuperVisitable, }; /// This trait is implemented for every type that can be folded, @@ -144,7 +144,7 @@ pub trait TypeFolder: Sized { r } - fn fold_const(&mut self, c: I::Const) -> I::Const { + fn fold_const(&mut self, c: Const) -> Const { c.super_fold_with(self) } @@ -213,7 +213,7 @@ pub trait FallibleTypeFolder: Sized { Ok(r) } - fn try_fold_const(&mut self, c: I::Const) -> Result { + fn try_fold_const(&mut self, c: Const) -> Result, Self::Error> { c.try_super_fold_with(self) } @@ -448,7 +448,7 @@ impl TypeFolder for Shifter { } } - fn fold_const(&mut self, ct: I::Const) -> I::Const { + fn fold_const(&mut self, ct: Const) -> Const { match ct.kind() { ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ct) if debruijn >= self.current_index => @@ -572,7 +572,7 @@ where if t.has_regions() { t.super_fold_with(self) } else { t } } - fn fold_const(&mut self, ct: I::Const) -> I::Const { + fn fold_const(&mut self, ct: Const) -> Const { if ct.has_regions() { ct.super_fold_with(self) } else { ct } } @@ -698,7 +698,7 @@ impl TypeFolder for RigidnessFolder { } } - fn fold_const(&mut self, c: I::Const) -> I::Const { + fn fold_const(&mut self, c: Const) -> Const { if !self.mode.needs_change(&c) { return c; } @@ -708,13 +708,13 @@ impl TypeFolder for RigidnessFolder { let alias_const = alias_const.fold_with(self); match self.mode { RigidnessFoldMode::AllToRigid => { - I::Const::new_alias(self.cx, ty::IsRigid::Yes, alias_const) + Const::new_alias(self.cx, ty::IsRigid::Yes, alias_const) } RigidnessFoldMode::AllToNonRigid => { - I::Const::new_alias(self.cx(), ty::IsRigid::No, alias_const) + Const::new_alias(self.cx(), ty::IsRigid::No, alias_const) } RigidnessFoldMode::OpaqueToNonRigid | RigidnessFoldMode::TypeToRigid => { - I::Const::new_alias(self.cx(), is_rigid, alias_const) + Const::new_alias(self.cx(), is_rigid, alias_const) } } } diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index b42a3c3159a07..31c87f7b1684e 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -3,7 +3,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; use rustc_type_ir_macros::GenericTypeVisitable; -use crate::{Interner, Region}; +use crate::{Const, Interner, Region}; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] #[derive(GenericTypeVisitable)] @@ -14,7 +14,7 @@ use crate::{Interner, Region}; pub enum GenericArgKind { Lifetime(Region), Type(I::Ty), - Const(I::Const), + Const(Const), } impl Eq for GenericArgKind {} diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index a86a07edb902f..22ebedd9f7e3c 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -11,7 +11,7 @@ use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; use crate::solve::{TyOrConstInferVar, VisibleForLeakCheck}; use crate::{ - self as ty, Interner, PredicateProxy, Region, TyVid, TypeFoldable, TypeFolder, + self as ty, Const, Interner, PredicateProxy, Region, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -434,14 +434,14 @@ pub trait InferCtxtLike: Sized { fn shallow_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; fn shallow_resolve_float_var(&self, vid: ty::FloatVid) -> ::Ty; - fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> ::Const; + fn shallow_resolve_const_var(&self, vid: ty::ConstVid) -> Const; fn shallow_resolve_region_var(&self, vid: ty::RegionVid) -> Region; fn ty_or_const_infer_var_changed(&self, var: TyOrConstInferVar) -> bool; fn next_region_infer(&self) -> Region; fn next_ty_infer(&self) -> ::Ty; - fn next_const_infer(&self) -> ::Const; + fn next_const_infer(&self) -> Const; fn fresh_args_for_item( &self, def_id: ::DefId, @@ -478,7 +478,7 @@ pub trait InferCtxtLike: Sized { fn instantiate_ty_var_raw(&self, vid: ty::TyVid, ty: ::Ty); /// Use `instantiate_const_var` instead unless you have reasons to skip /// generalization. - fn instantiate_const_var_raw(&self, vid: ty::ConstVid, ct: ::Const); + fn instantiate_const_var_raw(&self, vid: ty::ConstVid, ct: Const); fn instantiate_ty_var>( &self, relation: &mut R, @@ -494,7 +494,7 @@ pub trait InferCtxtLike: Sized { relation: &mut R, target_is_expected: bool, target_vid: ty::ConstVid, - source_ct: ::Const, + source_ct: Const, ) -> RelateResult; fn set_tainted_by_errors(&self, e: ::ErrorGuaranteed); @@ -503,10 +503,7 @@ pub trait InferCtxtLike: Sized { &self, ty: ::Ty, ) -> ::Ty; - fn shallow_resolve_const( - &self, - ty: ::Const, - ) -> ::Const; + fn shallow_resolve_const(&self, ty: Const) -> Const; fn deeply_resolve_ignoring_regions(&self, value: T) -> T where @@ -694,7 +691,7 @@ impl, I: Interner> TypeFolder } } - fn fold_const(&mut self, c: I::Const) -> I::Const { + fn fold_const(&mut self, c: Const) -> Const { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { let resolved = self.delegate.shallow_resolve_const_var(vid); diff --git a/compiler/rustc_type_ir/src/pattern.rs b/compiler/rustc_type_ir/src/pattern.rs index 69b2c414695bc..dbd4ea4ad9867 100644 --- a/compiler/rustc_type_ir/src/pattern.rs +++ b/compiler/rustc_type_ir/src/pattern.rs @@ -5,7 +5,7 @@ use rustc_type_ir_macros::{ GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, }; -use crate::Interner; +use crate::{Const, Interner}; #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] @@ -14,7 +14,7 @@ use crate::Interner; derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) )] pub enum PatternKind { - Range { start: I::Const, end: I::Const }, + Range { start: Const, end: Const }, Or(I::PatList), NotNull, } diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index d6276ea0062bd..946fff0d3a649 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -5,7 +5,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::{self as ty, Interner, Region}; +use crate::{self as ty, Const, Interner, Region}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. @@ -33,13 +33,13 @@ pub enum ClauseKind { /// Ensures that a const generic argument to a parameter `const N: u8` /// is of type `u8`. - ConstArgHasType(I::Const, I::Ty), + ConstArgHasType(Const, I::Ty), /// No syntax: `T` well-formed. WellFormed(I::Term), /// Constant initializer must evaluate successfully. - ConstEvaluatable(I::Const), + ConstEvaluatable(Const), /// Enforces the constness of the clause we're calling. Like a projection /// goal from a where clause, it's always going to be paired with a @@ -88,7 +88,7 @@ pub enum PredicateKind { Coerce(ty::CoercePredicate), /// Constants must be equal. The first component is the const that is expected. - ConstEquate(I::Const, I::Const), + ConstEquate(Const, Const), /// A marker predicate that is always ambiguous. /// Used for coherence to mark opaque types as possibly equal to each other but ambiguous. diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 0dd79d8d0449e..58763593f9b7e 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -9,6 +9,8 @@ use rustc_macros::StableHash_NoContext; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::{debug, instrument}; +use crate::Const; + // Workaround for TransitiveRelation being in rustc_data_structures which isn't accessible on stable #[cfg(not(feature = "nightly"))] #[derive(Default, Clone, Debug)] @@ -1227,7 +1229,7 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeRelation Ok(a) } - fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult { + fn consts(&mut self, a: Const, b: Const) -> RelateResult> { rustc_type_ir::relate::structurally_relate_consts(self, a, b) } diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index f6491bac642e3..74cb04ef86314 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -7,7 +7,7 @@ use tracing::{instrument, trace}; use crate::error::{ExpectedFound, TypeError}; use crate::fold::TypeFoldable; use crate::inherent::*; -use crate::{self as ty, Interner, Region}; +use crate::{self as ty, Const, Interner, Region}; pub mod combine; pub mod solver_relating; @@ -90,7 +90,7 @@ pub trait TypeRelation: Sized { fn regions(&mut self, a: Region, b: Region) -> RelateResult>; - fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult; + fn consts(&mut self, a: Const, b: Const) -> RelateResult>; fn binders( &mut self, @@ -560,9 +560,9 @@ pub fn structurally_relate_tys>( /// See the HACKs below. pub fn structurally_relate_consts>( relation: &mut R, - mut a: I::Const, - mut b: I::Const, -) -> RelateResult { + mut a: Const, + mut b: Const, +) -> RelateResult> { trace!( "structurally_relate_consts::<{}>(a = {:?}, b = {:?})", std::any::type_name::(), diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 7b747141889fe..054dff869e650 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -10,7 +10,7 @@ use crate::inherent::*; use crate::relate::VarianceDiagInfo; use crate::solve::Goal; use crate::visit::TypeVisitableExt as _; -use crate::{self as ty, InferCtxtLike, Interner, TypingMode, Upcast}; +use crate::{self as ty, Const, InferCtxtLike, Interner, TypingMode, Upcast}; pub trait PredicateEmittingRelation::Interner>: TypeRelation @@ -143,9 +143,9 @@ where pub fn super_combine_consts( infcx: &Infcx, relation: &mut R, - a: I::Const, - b: I::Const, -) -> RelateResult + a: Const, + b: Const, +) -> RelateResult> where Infcx: InferCtxtLike, I: Interner, diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 1e8ff77e4d395..d42727ff9bd78 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -5,7 +5,7 @@ use crate::data_structures::DelayedSet; use crate::relate::combine::combine_ty_args; pub use crate::relate::*; use crate::solve::{Goal, VisibleForLeakCheck}; -use crate::{self as ty, InferCtxtLike, Interner, Region}; +use crate::{self as ty, Const, InferCtxtLike, Interner, Region}; pub trait RelateExt: InferCtxtLike { fn relate>( @@ -253,7 +253,7 @@ where } #[instrument(skip(self), level = "trace")] - fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult { + fn consts(&mut self, a: Const, b: Const) -> RelateResult> { super_combine_consts(self.infcx, self, a, b) } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 88d2184ed95b2..c6d88bb6603de 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -18,8 +18,8 @@ use crate::lang_items::SolverTraitLangItem; use crate::region_constraint::RegionConstraint; use crate::search_graph::PathKind; use crate::{ - self as ty, Canonical, CanonicalVarValues, CantBeErased, ConstVid, FloatVid, GenericArgKind, - InferConst, IntVid, Interner, TermKind, TyVid, TypingMode, Upcast, + self as ty, Canonical, CanonicalVarValues, CantBeErased, Const, ConstVid, FloatVid, + GenericArgKind, InferConst, IntVid, Interner, TermKind, TyVid, TypingMode, Upcast, }; pub type CanonicalInputData = @@ -1090,7 +1090,7 @@ impl TyOrConstInferVar { /// Tries to extract an inference variable from a constant, returns `None` /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). - fn maybe_from_const(ct: I::Const) -> Option { + fn maybe_from_const(ct: Const) -> Option { match ct.kind() { ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)), _ => None, diff --git a/compiler/rustc_type_ir/src/term_kind.rs b/compiler/rustc_type_ir/src/term_kind.rs index ed23b196fe269..ae2b44780b774 100644 --- a/compiler/rustc_type_ir/src/term_kind.rs +++ b/compiler/rustc_type_ir/src/term_kind.rs @@ -8,7 +8,7 @@ use rustc_type_ir_macros::{ }; use crate::inherent::*; -use crate::{self as ty, AliasTerm, Interner}; +use crate::{self as ty, AliasTerm, Const, Interner}; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] #[derive(GenericTypeVisitable)] @@ -18,7 +18,7 @@ use crate::{self as ty, AliasTerm, Interner}; )] pub enum TermKind { Ty(I::Ty), - Const(I::Const), + Const(Const), } impl Eq for TermKind {} @@ -223,7 +223,7 @@ impl AliasTerm { .into() }; let alias_const = |kind| { - I::Const::new_alias(interner, is_rigid, ty::AliasConst::new(interner, kind, self.args)) + Const::new_alias(interner, is_rigid, ty::AliasConst::new(interner, kind, self.args)) .into() }; match self.kind { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 248ba00348749..68a1b479830e2 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -19,7 +19,7 @@ pub use self::closure::*; use crate::inherent::*; use crate::ty::AliasTy; use crate::{ - self as ty, BoundVarIndexKind, FloatTy, FreeAliasTy, InherentAliasTy, IntTy, Interner, + self as ty, BoundVarIndexKind, Const, FloatTy, FreeAliasTy, InherentAliasTy, IntTy, Interner, OpaqueAliasTy, ProjectionAliasTy, Region, UintTy, Unnormalized, }; @@ -187,7 +187,7 @@ pub enum TyKind { Str, /// An array with the given length. Written as `[T; N]`. - Array(I::Ty, I::Const), + Array(I::Ty, Const), /// A pattern newtype. /// diff --git a/compiler/rustc_type_ir/src/universe.rs b/compiler/rustc_type_ir/src/universe.rs index 1f38edd78023d..34210a0251fb8 100644 --- a/compiler/rustc_type_ir/src/universe.rs +++ b/compiler/rustc_type_ir/src/universe.rs @@ -4,7 +4,7 @@ use crate::data_structures::HashSet; use crate::inherent::*; use crate::visit::TypeVisitableExt; use crate::{ - ConstKind, InferCtxtLike, InferTy, Interner, Region, RegionKind, TyKind, TypeFoldable, + Const, ConstKind, InferCtxtLike, InferTy, Interner, Region, RegionKind, TyKind, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, UniverseIndex, }; @@ -130,7 +130,7 @@ impl< assert!(self.cache.insert(t), "we shouldn't visit {t:?} twice"); } - fn visit_const(&mut self, c: I::Const) { + fn visit_const(&mut self, c: Const) { if !Self::needs_visit(&c) { return; } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 1138d8cf9edad..008b6aeb239ee 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, PredicateProxy, Region, TypeFlags}; +use crate::{self as ty, Const, Interner, PredicateProxy, Region, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -112,7 +112,7 @@ pub trait TypeVisitor: Sized { } } - fn visit_const(&mut self, c: I::Const) -> Self::Result { + fn visit_const(&mut self, c: Const) -> Self::Result { c.super_visit_with(self) } @@ -475,7 +475,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { } #[inline] - fn visit_const(&mut self, c: I::Const) -> Self::Result { + fn visit_const(&mut self, c: Const) -> Self::Result { // Note: no `super_visit_with` call. if c.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -583,7 +583,7 @@ impl TypeVisitor for HasEscapingVarsVisitor { } } - fn visit_const(&mut self, ct: I::Const) -> Self::Result { + fn visit_const(&mut self, ct: Const) -> Self::Result { // If the outer-exclusive-binder is *strictly greater* than // `outer_index`, that means that `ct` contains some content // bound at `outer_index` or above (because From ddbacba20cd6f3be05c236023c21bf0c506337d4 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Thu, 17 Sep 2026 09:36:40 +0100 Subject: [PATCH 03/15] `use ConstExt` for methods that do not yet exist in `rustc_type_ir` --- compiler/rustc_borrowck/src/type_check/mod.rs | 1 + compiler/rustc_codegen_cranelift/src/base.rs | 1 + compiler/rustc_codegen_cranelift/src/debuginfo/types.rs | 1 + compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs | 1 + compiler/rustc_codegen_cranelift/src/unsize.rs | 1 + compiler/rustc_codegen_gcc/src/intrinsic/simd.rs | 1 + compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 1 + compiler/rustc_codegen_llvm/src/intrinsic.rs | 1 + compiler/rustc_codegen_ssa/src/base.rs | 1 + compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs | 1 + compiler/rustc_codegen_ssa/src/mir/constant.rs | 1 + compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 1 + compiler/rustc_codegen_ssa/src/mir/operand.rs | 1 + compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 1 + compiler/rustc_const_eval/src/const_eval/machine.rs | 1 + compiler/rustc_const_eval/src/const_eval/mod.rs | 1 + compiler/rustc_const_eval/src/const_eval/valtrees.rs | 1 + compiler/rustc_const_eval/src/interpret/cast.rs | 1 + compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs | 1 + compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs | 1 + compiler/rustc_hir_analysis/src/check/check.rs | 1 + compiler/rustc_hir_analysis/src/check/intrinsic.rs | 1 + compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 1 + compiler/rustc_hir_typeck/src/expr.rs | 1 + compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 1 + compiler/rustc_hir_typeck/src/inline_asm.rs | 1 + compiler/rustc_hir_typeck/src/pat.rs | 1 + compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_lint/src/types.rs | 1 + compiler/rustc_lint/src/unused/must_use.rs | 1 + compiler/rustc_middle/src/mir/consts.rs | 1 + compiler/rustc_middle/src/mir/pretty.rs | 1 + compiler/rustc_middle/src/mir/statement.rs | 1 + compiler/rustc_middle/src/ty/consts/valtree.rs | 1 + .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 1 + compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 1 + compiler/rustc_middle/src/ty/layout.rs | 1 + compiler/rustc_middle/src/ty/pattern.rs | 1 + compiler/rustc_middle/src/ty/sty.rs | 1 + compiler/rustc_middle/src/ty/typetree.rs | 1 + compiler/rustc_middle/src/ty/util.rs | 1 + compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs | 1 + compiler/rustc_mir_build/src/builder/matches/match_pair.rs | 1 + compiler/rustc_mir_build/src/builder/matches/mod.rs | 1 + compiler/rustc_mir_build/src/builder/scope.rs | 1 + compiler/rustc_mir_build/src/thir/constant.rs | 1 + compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 1 + compiler/rustc_mir_build/src/thir/pattern/mod.rs | 1 + compiler/rustc_mir_dataflow/src/move_paths/builder.rs | 1 + compiler/rustc_mir_transform/src/coroutine/layout.rs | 1 + compiler/rustc_mir_transform/src/elaborate_drop.rs | 1 + compiler/rustc_mir_transform/src/gvn.rs | 1 + compiler/rustc_mir_transform/src/instsimplify.rs | 1 + compiler/rustc_mir_transform/src/known_panics_lint.rs | 1 + compiler/rustc_mir_transform/src/promote_consts.rs | 1 + compiler/rustc_mir_transform/src/remove_zsts.rs | 1 + compiler/rustc_pattern_analysis/src/rustc.rs | 1 + compiler/rustc_public_bridge/src/context/impls.rs | 1 + .../rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs | 1 + compiler/rustc_symbol_mangling/src/legacy.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 1 + compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs | 1 + .../src/error_reporting/traits/ambiguity.rs | 1 + .../src/error_reporting/traits/fulfillment_errors.rs | 1 + .../src/error_reporting/traits/on_unimplemented.rs | 1 + .../src/error_reporting/traits/suggestions.rs | 1 + compiler/rustc_trait_selection/src/traits/fulfill.rs | 1 + compiler/rustc_trait_selection/src/traits/mod.rs | 1 + .../rustc_trait_selection/src/traits/query/dropck_outlives.rs | 1 + compiler/rustc_transmute/src/lib.rs | 1 + compiler/rustc_ty_utils/src/consts.rs | 1 + 71 files changed, 71 insertions(+) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6418c73173df0..3bd69a0ddcc37 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -24,6 +24,7 @@ use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::CastTy; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 506037c151148..638463b5cb438 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -12,6 +12,7 @@ use rustc_hir::attrs::lang_items::LangItem; use rustc_index::IndexVec; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv as _}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::config::OutputFilenames; diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index 18a0632a0939d..2eb4725fc5b20 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -3,6 +3,7 @@ use gimli::write::{AttributeValue, UnitEntryId}; use rustc_codegen_ssa::debuginfo::type_names; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 270ea4e88a999..f04c32a70390a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -3,6 +3,7 @@ use cranelift_codegen::ir::immediates::Offset32; use rustc_abi::Endian; use rustc_middle::ty::SimdAlign; +use rustc_middle::ty::consts::ConstExt; use super::*; use crate::prelude::*; diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 48fb0f6c7d4a8..efc89075cdeb2 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -3,6 +3,7 @@ //! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize` use rustc_codegen_ssa::base::validate_trivial_unsize; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 1416f4eec9c4a..9b102b2d9a8e8 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; #[cfg(feature = "master")] use rustc_hir as hir; use rustc_middle::mir::BinOp; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index e0fc60e1a9b7a..9b951584b66d4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -10,6 +10,7 @@ use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginf use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{ HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, }; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index db896fa9c0f2b..b45e4370b7883 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -19,6 +19,7 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::find_attr; use rustc_lint_defs::builtin::DEPRECATED_LLVM_INTRINSIC; use rustc_middle::mir::BinOp; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::offload_meta::OffloadMetadata; use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv}; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index de921a9cb0d1e..e054394ccade0 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -26,6 +26,7 @@ use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, ErrorHandled, Scalar}; use rustc_middle::mir::{BinOp, ConstValue}; use rustc_middle::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions}; use rustc_middle::query::Providers; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt, UintTy, Unnormalized}; use rustc_session::config::{self, EntryFnType}; diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 810253956b186..9cf68c6e3909c 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -20,6 +20,7 @@ use rustc_hashes::Hash64; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{ self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt, Unnormalized, diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 625e1dd8491db..b6f16f72b021e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,6 +1,7 @@ use rustc_abi::BackendRepr; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Ty}; use rustc_span::{bug, span_bug}; diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 22ab228e15b5f..e6b70ce2ca77b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,5 +1,6 @@ use rustc_abi::{Align, FieldIdx, WrappingRange}; use rustc_middle::mir::SourceInfo; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{ErrorGuaranteed, bug, span_bug, sym}; diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 5b07eb84f40d7..d11ba53e58c89 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -8,6 +8,7 @@ use rustc_abi::{ use rustc_hir::attrs::lang_items::LangItem; use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range}; use rustc_middle::mir::{self, ConstValue}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_session::config::{AnnotateMoves, DebugInfo, OptLevel}; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 130958f3705c9..3b33cf5a17602 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -5,6 +5,7 @@ use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT}; use rustc_index::IndexVec; use rustc_middle::mir; use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Mutability, Ty, TyCtxt}; use rustc_session::config::OptLevel; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index d176ee1628cb5..c0617c19263e7 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -13,6 +13,7 @@ use rustc_middle::mir; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; use rustc_middle::query::TyCtxtAt; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{self, FieldInfo, ScalarInt, Ty, TyCtxt}; use rustc_span::{Span, Symbol, bug, span_bug, sym}; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 58b8418707eff..1a08c166770cf 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -2,6 +2,7 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::mir; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{DUMMY_SP, bug}; use tracing::instrument; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index de8dd989c6a00..6cb327f1efca6 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -3,6 +3,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError}; use rustc_middle::traits::ObligationCause; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{LayoutCx, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{DUMMY_SP, bug}; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 79a3887d5123d..1f16aab095843 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -6,6 +6,7 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::CastKind; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_span::{bug, span_bug}; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs index 48218703c8ec1..3c45550016851 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs @@ -1,4 +1,5 @@ use rustc_middle::mir::BinOp; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::{mir, ty}; use rustc_span::{Symbol, span_bug, sym}; use tracing::trace; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 476ba405f19ca..ad191e9b4d763 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -3,6 +3,7 @@ use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{err_ub_format, mir, throw_unsup_format, ty}; use rustc_span::{Symbol, bug, span_bug, sym}; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8fde417b764d8..ded09d15ecee8 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -19,6 +19,7 @@ use rustc_macros::Diagnostic; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::util::Discr; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index cca93e8aef0ec..b566f6b04bf41 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -4,6 +4,7 @@ use rustc_errors::DiagMessage; use rustc_hir as hir; use rustc_hir::attrs::lang_items::LangItem; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol, sym}; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b659dd896aba0..c8b043086c0cb 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -42,6 +42,7 @@ use rustc_infer::traits::DynCompatibilityViolation; use rustc_lint_defs::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::middle::stability::AllowUnstable; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{ self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a8898acf3a415..dd5b521ca159e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -26,6 +26,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin}; use rustc_infer::traits::query::NoSolution; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt, Unnormalized}; use rustc_session::diagnostics::feature_err; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index ab8020a3182e0..7a2bd1a2aea7e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -18,6 +18,7 @@ use rustc_hir::{ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_hir_analysis::suggest_impl_trait; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_suggestion}; use rustc_middle::ty::{ self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index 2b1d9ed038b87..0048c638a6aba 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::ASM_SUB_REGISTER; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{ self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy, Unnormalized, }; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 81cdd278c3bc7..8aff5485277ad 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -21,6 +21,7 @@ use rustc_hir_analysis::autoderef::report_autoderef_recursion_limit_error; use rustc_infer::infer::RegionVariableOrigin; use rustc_lint_defs::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_middle::traits::PatternOriginExpr; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt, Unnormalized}; use rustc_session::diagnostics::feature_err; use rustc_span::edit_distance::find_best_match_for_name; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2d571d8b8e13d..ad12a437b1a07 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -33,6 +33,7 @@ use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateO // Lints from rustc_lint_defs pub use rustc_lint_defs::builtin::*; use rustc_lint_defs::{declare_lint, declare_lint_pass, fcw, impl_lint_pass}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 4d741e06198b5..d62fca02cf4cf 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::{Expr, ExprKind, HirId, find_attr}; use rustc_lint_defs::{declare_lint, declare_lint_pass, impl_lint_pass}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::{DUMMY_SP, Span, Symbol, bug, sym}; diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index 981d9df9c0f29..a637e8cf3b0f4 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, find_attr}; use rustc_infer::traits::util::elaborate; use rustc_lint_defs::{declare_lint, declare_lint_pass}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, Unnormalized}; use rustc_span::{Span, Symbol, sym}; use tracing::instrument; diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 9b12bd144a111..772976bb7a514 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -9,6 +9,7 @@ use rustc_type_ir::TypeVisitableExt; use super::interpret::ReportedErrorInfo; use crate::mir::interpret::{AllocId, AllocRange, ErrorHandled, GlobalAlloc, Scalar, alloc_range}; use crate::mir::{Promoted, pretty_print_const_value}; +use crate::ty::consts::ConstExt; use crate::ty::print::{pretty_print_const, with_no_trimmed_paths}; use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt}; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 870819d7a2b93..159a0f9883db3 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -18,6 +18,7 @@ use crate::mir::interpret::{ use crate::mir::visit::Visitor; use crate::mir::*; use crate::ty::CoroutineArgsExt; +use crate::ty::consts::ConstExt; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 22366f70fbe4e..b6542fb328aac 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -10,6 +10,7 @@ use tracing::instrument; use super::interpret::GlobalAlloc; use super::*; +use crate::ty::consts::ConstExt; use crate::ty::{CoroutineArgsExt, Unnormalized}; /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 9c4700b41d1ff..28e32a4a82d0d 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -11,6 +11,7 @@ use rustc_span::bug; use super::ScalarInt; use crate::mir::interpret::{ErrorHandled, Scalar}; +use crate::ty::consts::ConstExt; use crate::ty::print::{FmtPrinter, PrettyPrinter}; use crate::ty::{self, Ty, TyCtxt, ValTreeKind}; diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 6b0234c971830..61e3a40e363d9 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -4,6 +4,7 @@ use rustc_span::def_id::{LocalModId, ModId}; use smallvec::SmallVec; use tracing::instrument; +use crate::ty::consts::ConstExt; use crate::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypingEnv, Unnormalized}; /// Represents whether some type is inhabited in a given context. diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 60ea2bf49a046..078a171491520 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -53,6 +53,7 @@ use rustc_type_ir::TyKind::*; use tracing::instrument; use crate::query::Providers; +use crate::ty::consts::ConstExt; use crate::ty::{ self, AdtDef, DefId, Ty, TyCtxt, TypeVisitableExt, TypingEnv, VariantDef, Visibility, }; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 22fbb306849da..0cb8701634a3e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -21,6 +21,7 @@ use tracing::debug; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::TyCtxtAt; use crate::traits::ObligationCause; +use crate::ty::consts::ConstExt; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 2d73124265fc2..71d3bf0853f04 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -7,6 +7,7 @@ use rustc_type_ir::{self as ir, FlagComputation, Flags}; use super::TyCtxt; use crate::ty; +use crate::ty::consts::ConstExt; pub type PatternKind<'tcx> = ir::PatternKind>; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f4b1f0ce0881d..fe569bf282d36 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -27,6 +27,7 @@ use super::{AdtFlags, GenericParamDefKind}; use crate::infer::canonical::Canonical; use crate::traits::ObligationCause; use crate::ty::InferTy::*; +use crate::ty::consts::ConstExt; use crate::ty::{ self, AdtDef, Const, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv, Region, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, ValTree, diff --git a/compiler/rustc_middle/src/ty/typetree.rs b/compiler/rustc_middle/src/ty/typetree.rs index c2479e0c62bca..54cbc591c5fb3 100644 --- a/compiler/rustc_middle/src/ty/typetree.rs +++ b/compiler/rustc_middle/src/ty/typetree.rs @@ -2,6 +2,7 @@ use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_span::bug; use tracing::trace; +use crate::ty::consts::ConstExt; use crate::ty::context::TyCtxt; use crate::ty::{self, Ty}; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 31b7b719fa9cf..80bf33d98c923 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -25,6 +25,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; use crate::query::Providers; use crate::traits::ObligationCause; +use crate::ty::consts::ConstExt; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 695684452fc56..09c76d6beb4a1 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -8,6 +8,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::{CastTy, mir_cast_kind}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, UpvarArgs}; use rustc_span::{DUMMY_SP, Span, Spanned, bug}; diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 392712619a3f2..57ffee758b325 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use rustc_abi::FieldIdx; use rustc_middle::mir::{Pinnedness, Place, PlaceElem, ProjectionElem}; use rustc_middle::thir::{Ascription, DerefPatBorrowMode, FieldPat, Pat, PatKind}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_span::{Span, span_bug}; diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 6034d657a005e..f9c399797a400 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -17,6 +17,7 @@ use rustc_hir::{BindingMode, ByRef, LetStmt, LocalSource, Node}; use rustc_middle::middle::region::{self, TempLifetime}; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, ValTree, ValTreeKind}; use rustc_pattern_analysis::constructor::RangeEnd; use rustc_pattern_analysis::rustc::{DeconstructedPat, RustcPatCtxt}; diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 872ffec45f30a..4b3c224a84357 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -91,6 +91,7 @@ use rustc_lint_defs::Level; use rustc_middle::middle::region; use rustc_middle::mir::{self, *}; use rustc_middle::thir::{AdtExpr, AdtExprBase, ArmId, ExprId, ExprKind}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree}; use rustc_pattern_analysis::rustc::RustcPatCtxt; use rustc_span::{DUMMY_SP, Span, Spanned, bug, span_bug}; diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 667eff50a0d32..fa2b149f71926 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,6 +1,7 @@ use rustc_abi::Size; use rustc_ast::{self as ast, UintTy}; use rustc_hir::attrs::lang_items::LangItem; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, LitToConstInput, ScalarInt, Ty, TyCtxt, TypeVisitableExt as _}; use rustc_span::bug; use tracing::trace; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 8aa11ad89f4e9..a74590795bd7e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -12,6 +12,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::Obligation; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index ff3f643303972..d31ab31344545 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -19,6 +19,7 @@ use rustc_middle::thir::{ Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, LitToConstInput, Ty, TyCtxt, const_lit_matches_ty, diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index f22ce4079e58c..3c1c631285f96 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -2,6 +2,7 @@ use std::mem; use rustc_index::IndexVec; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{bug, span_bug}; use smallvec::{SmallVec, smallvec}; diff --git a/compiler/rustc_mir_transform/src/coroutine/layout.rs b/compiler/rustc_mir_transform/src/coroutine/layout.rs index a06ae343123d1..0ae39b1507b6a 100644 --- a/compiler/rustc_mir_transform/src/coroutine/layout.rs +++ b/compiler/rustc_mir_transform/src/coroutine/layout.rs @@ -33,6 +33,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_infer::traits::TraitErrors; use rustc_lint_defs::builtin::MUST_NOT_SUSPEND; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, Ty, TyCtxt, TypingMode}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index d9d9914d02bd4..0786d0cf42ba4 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -8,6 +8,7 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind}; use rustc_index::Idx; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_mir_dataflow::DropFlagState; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 78881d37a093b..81a41be1c62da 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -114,6 +114,7 @@ use rustc_index::{IndexVec, newtype_index}; use rustc_middle::mir::interpret::{AllocRange, GlobalAlloc}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_mir_dataflow::{Analysis, ResultsCursor}; diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index b3b3dd1241a71..9a39bd8d75d24 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -6,6 +6,7 @@ use rustc_hir::find_attr; use rustc_index::IndexVec; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{IntegerExt, ValidityRequirement}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout}; use rustc_span::{Symbol, bug, sym}; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index fc210ecebfa48..1c598af1af98e 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -15,6 +15,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_lint_defs::builtin::UNCONDITIONAL_PANIC; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{ self, ConstInt, GenericArgKind, GenericParamDefKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index b749d6d36cf84..43d058c7eef0c 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -23,6 +23,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, GenericArgs, List, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{Span, Spanned, bug, span_bug}; use tracing::{debug, instrument}; diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 09379fc252072..98f4009c15665 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -2,6 +2,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use crate::PassPolicy; diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 5e6b682626210..581f1061bb80c 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -9,6 +9,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_lint_defs::builtin::{NON_CONTIGUOUS_RANGE_ENDPOINTS, OVERLAPPING_RANGE_ENDPOINTS}; use rustc_middle::middle::stability::EvalResult; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index 70e2498ac350b..c653aac541c2a 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -11,6 +11,7 @@ use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::print::{ with_forced_trimmed_paths, with_no_trimmed_paths, with_resolve_crate_name, diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index c487914bc362f..0b3beb329e0f8 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -12,6 +12,7 @@ use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::find_attr; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, Const, ExistentialPredicate, FloatTy, FnSig, GenericArg, GenericArgKind, GenericArgsRef, diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index e2be87e6b271f..bebfd746e1f6b 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -5,6 +5,7 @@ use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_hashes::Hash64; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer}; use rustc_middle::ty::{ self, GenericArg, GenericArgKind, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index e0d9d6976bd14..fb9f242f60085 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -14,6 +14,7 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, PrintError, Printer}; use rustc_middle::ty::{ diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index c798e4e953051..6782f1892f54d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -60,6 +60,7 @@ use rustc_hir::{self as hir, find_attr}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::extension; use rustc_middle::traits::PatternOriginExpr; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt}; use rustc_middle::ty::print::{PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths}; use rustc_middle::ty::{ diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index a44d53cdfdd05..9ce2e38183ebb 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -11,6 +11,7 @@ use rustc_infer::traits::util::elaborate; use rustc_infer::traits::{ Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation, }; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::print::PrintPolyTraitClauseExt; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _, Unnormalized}; use rustc_session::diagnostics::feature_err_unstable_feature_bound; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 26d768e5b22e8..4cdffafe6a0ba 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -24,6 +24,7 @@ use rustc_infer::traits::{ImplSource, TraitErrors}; use rustc_middle::traits::SignatureMismatchData; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::print::{ PrintPolyTraitClauseExt, PrintPolyTraitRefExt as _, PrintTraitClauseExt as _, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index ed22d4f4ef246..2967dfb64e710 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -4,6 +4,7 @@ use rustc_hir as hir; use rustc_hir::attrs::diagnostic::{CustomDiagnostic, FilterOptions, FormatArgs}; use rustc_hir::def_id::LocalDefId; use rustc_hir::find_attr; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, GenericParamDef, GenericParamDefKind}; use rustc_span::Symbol; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 76567e4d27d1d..b9b4b732bf9dd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -24,6 +24,7 @@ use rustc_infer::traits::ImplSource; use rustc_middle::middle::privacy::Level; use rustc_middle::traits::IsConstable; use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::{ PrintPolyTraitClauseExt as _, PrintPolyTraitRefExt, PrintTraitClauseExt as _, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index f5a4ec9ae0494..aae323ae1671f 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -11,6 +11,7 @@ use rustc_infer::traits::{ TraitEngine, TraitErrors, }; use rustc_middle::ty::abstract_const::NotConstEvaluatable; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, Binder, Const, DelayedSet, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index aa676dab91bbc..8ad7fd4ac3a69 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -30,6 +30,7 @@ use rustc_errors::ErrorGuaranteed; pub use rustc_infer::traits::*; use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BottomUpFolder, Clause, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index e9e1cea48ba20..31d2e8620af90 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_infer::traits::TraitErrors; use rustc_infer::traits::query::type_op::DropckOutlives; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt, Unnormalized}; use rustc_span::Span; use thin_vec::ThinVec; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index e2e1b0a08e15a..53287dbe331ee 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -104,6 +104,7 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { use rustc_hir::attrs::lang_items::LangItem; + use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{Const, Region, Ty, TyCtxt}; use super::*; diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 6db234fd886ca..25ad657b9c92e 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -5,6 +5,7 @@ use rustc_middle::query::Providers; use rustc_middle::thir::visit; use rustc_middle::thir::visit::Visitor; use rustc_middle::ty::abstract_const::CastKind; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Expr, LitToConstInput, TyCtxt, TypeVisitableExt}; use rustc_middle::{mir, thir}; use rustc_span::Span; From eb64306c669db279f21ca913b734dc22e4028096 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Thu, 17 Sep 2026 09:36:40 +0100 Subject: [PATCH 04/15] Use `ConstExt` in clippy --- src/tools/clippy/clippy_lints/src/indexing_slicing.rs | 1 + src/tools/clippy/clippy_lints/src/large_const_arrays.rs | 1 + src/tools/clippy/clippy_lints/src/large_stack_arrays.rs | 1 + src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs | 1 + src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs | 1 + src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs | 1 + src/tools/clippy/clippy_lints/src/matches/single_match.rs | 1 + src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs | 1 + src/tools/clippy/clippy_lints/src/methods/utils.rs | 1 + src/tools/clippy/clippy_lints/src/trailing_empty_array.rs | 1 + src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 1 + src/tools/clippy/clippy_utils/src/ty/mod.rs | 1 + 13 files changed, 13 insertions(+) diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index 107ab36741b2b..cd71a1e712c22 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -6,6 +6,7 @@ use clippy_utils::{higher, is_from_proc_macro, is_in_test, sym}; use rustc_ast::ast::RangeLimits; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty}; declare_clippy_lint! { diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 4d8ef09d17da3..d395d7b53c607 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -5,6 +5,7 @@ use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Ty, Unnormalized}; +use rustc_middle::ty::consts::ConstExt; use rustc_span::{BytePos, Pos as _, Span}; declare_clippy_lint! { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 49d4fe478cdf4..6762083fd324e 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -10,6 +10,7 @@ use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Span; +use rustc_middle::ty::consts::ConstExt; declare_clippy_lint! { /// ### What it does diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index cc458e54d16e9..0789a7f007ea7 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -14,6 +14,7 @@ use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{self, EarlyBinder, Ty}; +use rustc_middle::ty::consts::ConstExt; pub(super) fn check( cx: &LateContext<'_>, diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs index ec0c4fb23390b..b0ddec9513722 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs @@ -13,6 +13,7 @@ use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Pat, PatKind, StmtKind} use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; +use rustc_middle::ty::consts::ConstExt; use std::fmt::Display; /// Checks for `for` loops that sequentially copy items from one slice-like diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index e72842d72f5cb..71676c5007407 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -15,6 +15,7 @@ use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{BinOpKind, BorrowKind, Closure, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath}; use rustc_lint::LateContext; use rustc_middle::middle::region; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{Span, SyntaxContext}; diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs index f3e7d080237c8..6c550a63a5034 100644 --- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs @@ -12,6 +12,7 @@ use rustc_hir::intravisit::{Visitor, walk_pat}; use rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, StmtKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, AdtDef, TyCtxt, TypeckResults, VariantDef}; +use rustc_middle::ty::consts::ConstExt; use rustc_span::Span; use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE}; diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs index 7ec9021af11d8..54b29b06b35c1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs @@ -5,6 +5,7 @@ use clippy_utils::{expr_or_init, sym}; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty; use super::ITER_OUT_OF_BOUNDS; diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index 9e7764fa19c80..6860b920fa82f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -5,6 +5,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, QPath, Stmt, use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::consts::ConstExt; use rustc_span::Span; use rustc_span::symbol::sym; diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 9fa66fc86c305..22f2ed3b3e518 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -1,3 +1,4 @@ +use rustc_middle::ty::consts::ConstExt; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{has_repr_attr, is_in_test}; use rustc_hir::{Item, ItemKind}; diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs index c339affc3e8ba..1f0f678668b17 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -8,6 +8,7 @@ use clippy_utils::{SpanlessEq, is_from_proc_macro}; use core::ops::ControlFlow::{Break, Continue}; use core::{iter, mem}; use rustc_ast::LitKind; +use rustc_middle::ty::consts::ConstExt; use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list}; use rustc_data_structures::packed::Pu128; use rustc_hir::intravisit::Visitor; diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 192ce4df77c2a..890fc7cb4e947 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -17,6 +17,7 @@ use rustc_hir::{ BinOpKind, Block, ConstArgKind, ConstBlock, ConstItemRhs, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath, TyKind, UnOp, }; +use rustc_middle::ty::consts::ConstExt; use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::interpret::{Scalar, alloc_range}; diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index ca8b54a6de58b..7bef459baf153 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -20,6 +20,7 @@ use rustc_lint::unused::must_use::{IsTyMustUse, MustUsePath, is_ty_must_use}; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::Scalar; use rustc_middle::traits::EvaluationResult; +use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind}; use rustc_middle::ty::layout::{LayoutError, LayoutOf as _, TyAndLayout}; use rustc_middle::ty::{ From 0a7563bb6f9e2cf59384bc5e12a95385b13aefd4 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Thu, 17 Sep 2026 14:42:03 +0100 Subject: [PATCH 05/15] Add better code comments for peculiarities --- compiler/rustc_middle/src/ty/context.rs | 4 +--- compiler/rustc_type_ir/src/interner.rs | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fdfa05048e936..68fccf32469b4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1730,9 +1730,7 @@ impl<'a, 'tcx> Lift> for Interned<'a, RegionKind<'a>> { } } -// `rustc_type_ir::Const` is only the generic wrapper; lifting it delegates -// to `I::InternedConstKind`, so the concrete interned const representation -// must itself implement `Lift`. +// FIXME: unclear why exactly the macro doesn't work. impl<'a, 'tcx> Lift> for Interned<'a, WithCachedTypeInfo>> { type Lifted = Interned<'tcx, WithCachedTypeInfo>>; diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index a81b8289ac067..5ca10f77a1868 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -177,6 +177,10 @@ pub trait Interner: type Symbol: Symbol; // Things stored inside of tys + + // `TypeVisitable` is required to prevent a problem where the flags + // on `Const` indicated that an error was present, as the visitor could no + // longer reach the corresponding ErrorGuaranteed type ErrorGuaranteed: Copy + Debug + Hash + Eq + TypeVisitable; type BoundExistentialPredicates: BoundExistentialPredicates; type AllocId: Copy + Debug + Hash + Eq; From c973b5051072d339c21a3e9493ff0fabac8f8f97 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 18 Sep 2026 23:47:48 -0400 Subject: [PATCH 06/15] Avoid generating overlapping assignments in DSE --- .../src/dead_store_elimination.rs | 7 +++++ ...eadStoreElimination-final.panic-abort.diff | 2 +- ...adStoreElimination-final.panic-unwind.diff | 2 +- ...eadStoreElimination-final.panic-abort.diff | 16 ++++++++++ ...adStoreElimination-final.panic-unwind.diff | 16 ++++++++++ .../dead-store-elimination/call_arg_copy.rs | 29 ++++++++++++++----- 6 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-abort.diff create mode 100644 tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-unwind.diff diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 9b0e2a0663eca..7c41217f402ff 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -63,6 +63,13 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { loc, ); + // The logic in LivenessTransferFunction isn't quite what we need; it ignores call + // destinations that are just locals because they are killed by the call, which makes + // it eligible to be moved-from in the argument list. That's backwards. + if !destination.is_indirect() { + state.insert(destination.local); + } + for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() { if let Operand::Copy(place) = *arg && !place.is_indirect() diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-abort.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-abort.diff index 012dd7d88a5f0..2c4e7ae552844 100644 --- a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-abort.diff +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-abort.diff @@ -5,7 +5,7 @@ let mut _0: (); bb0: { - _1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind unreachable]; + _1[_2] = identity::(copy _2) -> [return: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-unwind.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-unwind.diff index fcd0ae43e2897..86f9b93130d72 100644 --- a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-unwind.diff +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-unwind.diff @@ -5,7 +5,7 @@ let mut _0: (); bb0: { - _1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind continue]; + _1[_2] = identity::(copy _2) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-abort.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-abort.diff new file mode 100644 index 0000000000000..d4d49d0fb79e7 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-abort.diff @@ -0,0 +1,16 @@ +- // MIR for `ret_is_arg` before DeadStoreElimination-final ++ // MIR for `ret_is_arg` after DeadStoreElimination-final + + fn ret_is_arg(_1: [u64; 5]) -> [u64; 5] { + let mut _0: [u64; 5]; + + bb0: { + _1 = identity::<[u64; 5]>(copy _1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + _0 = copy _1; + return; + } + } + diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-unwind.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-unwind.diff new file mode 100644 index 0000000000000..d4d49d0fb79e7 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.ret_is_arg.DeadStoreElimination-final.panic-unwind.diff @@ -0,0 +1,16 @@ +- // MIR for `ret_is_arg` before DeadStoreElimination-final ++ // MIR for `ret_is_arg` after DeadStoreElimination-final + + fn ret_is_arg(_1: [u64; 5]) -> [u64; 5] { + let mut _0: [u64; 5]; + + bb0: { + _1 = identity::<[u64; 5]>(copy _1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + _0 = copy _1; + return; + } + } + diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs index 00a9a49c2abb8..1a7f9a1494dbe 100644 --- a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs @@ -6,6 +6,7 @@ #![feature(custom_mir)] #![allow(internal_features)] +use std::convert::identity; use std::intrinsics::mir::*; #[inline(never)] @@ -40,22 +41,17 @@ fn move_packed(packed: Packed) { } } -#[inline(never)] -fn passthrough_usize(a: usize) -> usize { - a -} - // EMIT_MIR call_arg_copy.move_index.DeadStoreElimination-final.diff #[custom_mir(dialect = "analysis")] fn move_index(a: [usize; 10], b: usize) { // CHECK-LABEL: fn move_index( - // CHECK: = passthrough_usize(copy _2) + // CHECK: = identity::(copy _2) mir! { { // The index is used again after the operand is evaluated to - // evaluate the destionation place, so the argument cannot be turned + // evaluate the destination place, so the argument cannot be turned // into a move. - Call(a[b] = passthrough_usize(b), ReturnTo(ret), UnwindContinue()) + Call(a[b] = identity(b), ReturnTo(ret), UnwindContinue()) } ret = { Return() @@ -63,8 +59,25 @@ fn move_index(a: [usize; 10], b: usize) { } } +// EMIT_MIR call_arg_copy.ret_is_arg.DeadStoreElimination-final.diff +#[custom_mir(dialect = "runtime")] +fn ret_is_arg(x: [u64; 5]) -> [u64; 5] { + // CHECK-LABEL: fn ret_is_arg(_1 + // CHECK: _1 = identity::<[u64; 5]>(copy _1) -> + mir! { + { + Call(x = identity(x), ReturnTo(bb1), UnwindUnreachable()) + } + bb1 = { + RET = x; + Return() + } + } +} + fn main() { move_simple(1); move_packed(Packed { x: 0, y: 1 }); move_index([0; _], 1); + ret_is_arg([0; 5]); } From 5e86855354b3dde36c3de271cf600ce6b9d7e46d Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Mon, 21 Sep 2026 17:13:27 +0600 Subject: [PATCH 07/15] emit the constant pattern note for raw identifier bindings `is_const_pat_that_looks_like_binding` matched the pattern snippet against a plain identifier so the `#` in `let r#x = 0` rejected it and the binding lost both the label pointing at `const x` and the `introduce a variable instead` suggestion. strip a leading `r#` before the check and render the const name with `to_ident_string` in the label so a keyword name prints as `r#fn`. fixes https://github.com/rust-lang/rust/issues/162949 --- .../src/thir/pattern/check_match.rs | 15 ++++-- tests/ui/consts/const-pattern-irrefutable.rs | 14 ++++++ .../consts/const-pattern-irrefutable.stderr | 48 ++++++++++++++++--- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 3414ee751585c..5b4f7a79d4bac 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -678,10 +678,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, pat) { let span = self.tcx.def_span(def_id); - let variable = self.tcx.item_name(def_id).to_string(); + let name = self.tcx.item_name(def_id); // When we encounter a constant as the binding name, point at the `const` definition. - interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() }); - interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable }); + interpreted_as_const = + Some(InterpretedAsConst { span, variable: name.to_ident_string() }); + // The suggested name is suffixed, so it is never a keyword and never needs `r#`. + interpreted_as_const_sugg = + Some(InterpretedAsConstSugg { span: pat.span, variable: name.to_string() }); } else if let PatKind::Constant { .. } = pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { @@ -1231,7 +1234,11 @@ fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx> // `::` namespace separators or other non-identifier characters. if let ty::AliasConstKind::Free { def_id } = pat.extra.as_deref()?.expanded_const? && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span) - && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') + && snippet + .strip_prefix("r#") + .unwrap_or(&snippet) + .chars() + .all(|c| c.is_alphanumeric() || c == '_') { Some(def_id) } else { diff --git a/tests/ui/consts/const-pattern-irrefutable.rs b/tests/ui/consts/const-pattern-irrefutable.rs index e131fd27d532c..f0f5fc90d5195 100644 --- a/tests/ui/consts/const-pattern-irrefutable.rs +++ b/tests/ui/consts/const-pattern-irrefutable.rs @@ -13,6 +13,12 @@ use foo::d; const a: u8 = 2; //~^ NOTE missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable +const g: u8 = 2; +//~^ NOTE missing patterns are not covered because `g` is interpreted as a constant pattern, not a new variable + +const r#fn: u8 = 2; +//~^ NOTE missing patterns are not covered because `r#fn` is interpreted as a constant pattern, not a new variable + #[derive(PartialEq)] struct S { foo: u8, @@ -41,5 +47,13 @@ fn main() { //~| HELP introduce a variable instead foo: 1, }; + let r#g = 4; + //~^ ERROR refutable pattern in local binding + //~| NOTE patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + //~| HELP introduce a variable instead + let r#fn = 4; + //~^ ERROR refutable pattern in local binding + //~| NOTE patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + //~| HELP introduce a variable instead fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115). } diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr index f52ebc313339c..a59b17e41c799 100644 --- a/tests/ui/consts/const-pattern-irrefutable.stderr +++ b/tests/ui/consts/const-pattern-irrefutable.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:26:9 + --> $DIR/const-pattern-irrefutable.rs:32:9 | LL | const a: u8 = 2; | ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable @@ -16,7 +16,7 @@ LL | let a_var = 4; | ++++ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:30:9 + --> $DIR/const-pattern-irrefutable.rs:36:9 | LL | pub const b: u8 = 2; | --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable @@ -34,7 +34,7 @@ LL + let b_var = 4; | error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:34:9 + --> $DIR/const-pattern-irrefutable.rs:40:9 | LL | pub const d: (u8, u8) = (2, 1); | --------------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable @@ -51,7 +51,7 @@ LL | let d_var = (4, 4); | ++++ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:38:9 + --> $DIR/const-pattern-irrefutable.rs:44:9 | LL | const e: S = S { | ---------- missing patterns are not covered because `e` is interpreted as a constant pattern, not a new variable @@ -62,7 +62,7 @@ LL | let e = S { = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `S` defined here - --> $DIR/const-pattern-irrefutable.rs:17:8 + --> $DIR/const-pattern-irrefutable.rs:23:8 | LL | struct S { | ^ @@ -72,6 +72,42 @@ help: introduce a variable instead LL | let e_var = S { | ++++ -error: aborting due to 4 previous errors +error[E0005]: refutable pattern in local binding + --> $DIR/const-pattern-irrefutable.rs:50:9 + | +LL | const g: u8 = 2; + | ----------- missing patterns are not covered because `g` is interpreted as a constant pattern, not a new variable +... +LL | let r#g = 4; + | ^^^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html + = note: the matched value is of type `u8` +help: introduce a variable instead + | +LL - let r#g = 4; +LL + let g_var = 4; + | + +error[E0005]: refutable pattern in local binding + --> $DIR/const-pattern-irrefutable.rs:54:9 + | +LL | const r#fn: u8 = 2; + | -------------- missing patterns are not covered because `r#fn` is interpreted as a constant pattern, not a new variable +... +LL | let r#fn = 4; + | ^^^^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html + = note: the matched value is of type `u8` +help: introduce a variable instead + | +LL - let r#fn = 4; +LL + let fn_var = 4; + | + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0005`. From 919170b08cc014c8e85709dd80efeed2bac74562 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 21 Sep 2026 12:24:34 +0200 Subject: [PATCH 08/15] remove unnecessary restriction with next-solver --- .../src/region_infer/opaque_types/mod.rs | 55 +++++++++---------- ...tderr => lifetime_mismatch.current.stderr} | 8 +-- .../lifetime_mismatch.rs | 7 ++- ...f-uses-in-one-fn-lifetimes.current.stderr} | 4 +- .../multiple-def-uses-in-one-fn-lifetimes.rs | 5 +- 5 files changed, 42 insertions(+), 37 deletions(-) rename tests/ui/type-alias-impl-trait/{lifetime_mismatch.stderr => lifetime_mismatch.current.stderr} (84%) rename tests/ui/type-alias-impl-trait/{multiple-def-uses-in-one-fn-lifetimes.stderr => multiple-def-uses-in-one-fn-lifetimes.current.stderr} (78%) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index ad15c5750b092..069f6b598e19c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -362,11 +362,11 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( DefinitionSiteHiddenType::new_error(tcx, guar) }); - // Sometimes, when the hidden type is an inference variable, it can happen that - // the hidden type becomes the opaque type itself. In this case, this was an opaque - // usage of the opaque type and we can ignore it. This check is mirrored in typeck's - // writeback. if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() { + // Sometimes, when the hidden type is an inference variable, it can happen that + // the hidden type becomes the opaque type itself. In this case, this was an opaque + // usage of the opaque type and we can ignore it. This check is mirrored in typeck's + // writeback. if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) = hidden_type.ty.skip_binder().kind() && def_id == opaque_type_key.def_id.to_def_id() @@ -374,32 +374,31 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( { continue; } - } - // Check that all opaque types have the same region parameters if they have the same - // non-region parameters. This is necessary because within the new solver we perform - // various query operations modulo regions, and thus could unsoundly select some impls - // that don't hold. - // - // FIXME(-Znext-solver): This isn't necessary after all. We can remove this check again. - if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert( - rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key), - (opaque_type_key, hidden_type.span), - ) && let Some((arg1, arg2)) = std::iter::zip( - prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), - opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), - ) - .find(|(arg1, arg2)| arg1 != arg2) - { - errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam( - LifetimeMismatchOpaqueParam { - arg: arg1, - prev: arg2, - span: prev_span, - prev_span: hidden_type.span, - }, - )); + // Check that all opaque types have the same region parameters if they have the same + // non-region parameters. This is necessary because within the new solver we perform + // various query operations modulo regions, and thus could unsoundly select some impls + // that don't hold. + if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert( + rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key), + (opaque_type_key, hidden_type.span), + ) && let Some((arg1, arg2)) = std::iter::zip( + prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), + opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), + ) + .find(|(arg1, arg2)| arg1 != arg2) + { + errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam( + LifetimeMismatchOpaqueParam { + arg: arg1, + prev: arg2, + span: prev_span, + prev_span: hidden_type.span, + }, + )); + } } + add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type); } } diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr b/tests/ui/type-alias-impl-trait/lifetime_mismatch.current.stderr similarity index 84% rename from tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr rename to tests/ui/type-alias-impl-trait/lifetime_mismatch.current.stderr index 719748edc011f..83ed7ae17902c 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.current.stderr @@ -1,5 +1,5 @@ error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:7:5 + --> $DIR/lifetime_mismatch.rs:10:5 | LL | (x, y) | ^^^^^^ @@ -8,13 +8,13 @@ LL | (x, y) | lifetime `'b` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:7:5 + --> $DIR/lifetime_mismatch.rs:10:5 | LL | (x, y) | ^^^^^^ error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:15:5 + --> $DIR/lifetime_mismatch.rs:18:5 | LL | (i, j) | ^^^^^^ @@ -23,7 +23,7 @@ LL | (i, j) | lifetime `'y` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:15:5 + --> $DIR/lifetime_mismatch.rs:18:5 | LL | (i, j) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs index b58840718a354..4a8320e922a2e 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver=globally +//@[next] check-pass #![feature(type_alias_impl_trait)] type Foo<'a> = impl Sized; @@ -5,7 +8,7 @@ type Foo<'a> = impl Sized; #[define_opaque(Foo)] fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) { (x, y) - //~^ ERROR opaque type used twice with different lifetimes + //[current]~^ ERROR opaque type used twice with different lifetimes } type Bar<'a, 'b> = impl std::fmt::Debug; @@ -13,7 +16,7 @@ type Bar<'a, 'b> = impl std::fmt::Debug; #[define_opaque(Bar)] fn bar<'x, 'y>(i: &'x i32, j: &'y i32) -> (Bar<'x, 'y>, Bar<'y, 'x>) { (i, j) - //~^ ERROR opaque type used twice with different lifetimes + //[current]~^ ERROR opaque type used twice with different lifetimes } fn main() { diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.current.stderr similarity index 78% rename from tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr rename to tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.current.stderr index 03f2b1c532a00..fb67f6ffa44e4 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.current.stderr @@ -1,5 +1,5 @@ error: opaque type used twice with different lifetimes - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5 + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:10:5 | LL | (i, j) | ^^^^^^ @@ -8,7 +8,7 @@ LL | (i, j) | lifetime `'y` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5 + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:10:5 | LL | (i, j) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs index 39e4912ae3af6..f1c0bc190108b 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver=globally +//@[next] check-pass #![feature(type_alias_impl_trait)] type Foo<'a, 'b> = impl std::fmt::Debug; @@ -5,7 +8,7 @@ type Foo<'a, 'b> = impl std::fmt::Debug; #[define_opaque(Foo)] fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { (i, j) - //~^ ERROR opaque type used twice with different lifetimes + //[current]~^ ERROR opaque type used twice with different lifetimes } fn main() {} From db6e110a114382fd2f1912354272c2f51d01ddca Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 19 Oct 2025 10:03:06 +0100 Subject: [PATCH 09/15] visit_nested_body and visit_fn for LateLint should return earlier if typeck is tainted We started to check typeck result's tainted_by_errors in check_pat for LateLint, But ideally the check should be in a better place which all lints profit from it. --- compiler/rustc_lint/src/builtin.rs | 5 +---- compiler/rustc_lint/src/late.rs | 21 +++++++++++++++++-- tests/crashes/138361.rs | 6 ------ ...ng-constant-evaluation-cause-dead-code.rs} | 0 ...onstant-evaluation-cause-dead-code.stderr} | 4 ++-- ...ng-constant-evaluation-cause-ice-in-sty.rs | 5 +++++ ...onstant-evaluation-cause-ice-in-sty.stderr | 17 +++++++++++++++ 7 files changed, 44 insertions(+), 14 deletions(-) delete mode 100644 tests/crashes/138361.rs rename tests/ui/consts/{do-not-ice-long-constant-evaluation-in-for-loop.rs => long-constant-evaluation-cause-dead-code.rs} (100%) rename tests/ui/consts/{do-not-ice-long-constant-evaluation-in-for-loop.stderr => long-constant-evaluation-cause-dead-code.stderr} (78%) create mode 100644 tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.rs create mode 100644 tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.stderr diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2d571d8b8e13d..d4f213833aa48 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -148,10 +148,7 @@ declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]); impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns { fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) { - // The result shouldn't be tainted, otherwise it will cause ICE. - if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind - && cx.typeck_results().tainted_by_errors.is_none() - { + if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind { let variant = cx .typeck_results() .pat_ty(pat) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index ac185c65aa127..93ce4118c0ab7 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -99,7 +99,15 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas // The body and typeck results are also set in `visit_fn`. // Only fetch the results if this is for a new body. if old_enclosing_body != Some(body_id) && !self.actually_rustdoc { - self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id)); + let typeck_results = self.context.tcx.typeck_body(body_id); + + // To avoid ICE, skip visiting the body if the typeck_results is tainted. + if typeck_results.tainted_by_errors.is_some() { + self.context.enclosing_body = old_enclosing_body; + self.context.typeck_results = old_typeck_results; + return; + } + self.context.typeck_results = Some(typeck_results); } let body = self.context.tcx.hir_body(body_id); @@ -189,7 +197,16 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas let old_enclosing_body = self.context.enclosing_body.replace(body_id); let old_typeck_results = self.context.typeck_results; if !self.actually_rustdoc { - self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id)); + let typeck_results = self.context.tcx.typeck_body(body_id); + + // To avoid ICE, skip visiting the body if the typeck_results is tainted. + if typeck_results.tainted_by_errors.is_some() { + self.context.enclosing_body = old_enclosing_body; + self.context.typeck_results = old_typeck_results; + return; + } + + self.context.typeck_results = Some(typeck_results); } let body = self.context.tcx.hir_body(body_id); lint_callback!(self, check_fn, fk, decl, body, span, id); diff --git a/tests/crashes/138361.rs b/tests/crashes/138361.rs deleted file mode 100644 index 8661ed374744a..0000000000000 --- a/tests/crashes/138361.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #138361 - -fn main() { - [0; loop{}]; - std::mem::transmute(4) -} diff --git a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs b/tests/ui/consts/long-constant-evaluation-cause-dead-code.rs similarity index 100% rename from tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs rename to tests/ui/consts/long-constant-evaluation-cause-dead-code.rs diff --git a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr b/tests/ui/consts/long-constant-evaluation-cause-dead-code.stderr similarity index 78% rename from tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr rename to tests/ui/consts/long-constant-evaluation-cause-dead-code.stderr index c28f37bc16705..08160f8c78166 100644 --- a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr +++ b/tests/ui/consts/long-constant-evaluation-cause-dead-code.stderr @@ -1,5 +1,5 @@ error: constant evaluation is taking a long time - --> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14 + --> $DIR/long-constant-evaluation-cause-dead-code.rs:10:14 | LL | [(); loop {}]; | ^^^^^^^ @@ -7,7 +7,7 @@ LL | [(); loop {}]; = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated - --> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14 + --> $DIR/long-constant-evaluation-cause-dead-code.rs:10:14 | LL | [(); loop {}]; | ^^^^^^^ diff --git a/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.rs b/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.rs new file mode 100644 index 0000000000000..04d0f7ee2de84 --- /dev/null +++ b/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.rs @@ -0,0 +1,5 @@ +// The test confirms ICE-138361 is fixed. +fn main() { + [0; loop{}]; //~ ERROR constant evaluation is taking a long time + std::mem::transmute(4) +} diff --git a/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.stderr b/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.stderr new file mode 100644 index 0000000000000..58c62d61adaab --- /dev/null +++ b/tests/ui/consts/long-constant-evaluation-cause-ice-in-sty.stderr @@ -0,0 +1,17 @@ +error: constant evaluation is taking a long time + --> $DIR/long-constant-evaluation-cause-ice-in-sty.rs:3:7 + | +LL | [0; loop{}]; + | ^^^^^^ + | + = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. + If your compilation actually takes a long time, you can safely allow the lint +help: the constant being evaluated + --> $DIR/long-constant-evaluation-cause-ice-in-sty.rs:3:7 + | +LL | [0; loop{}]; + | ^^^^^^ + = note: `#[deny(long_running_const_eval)]` on by default + +error: aborting due to 1 previous error + From 28b5293debd90e0ad9b8ccb937c03e499cfc2170 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 21 Sep 2026 17:16:37 +0200 Subject: [PATCH 10/15] add field_projections fixme --- .../src/traits/select/candidate_assembly.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 8509be2fb6dec..120f83c14b5c7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -1494,6 +1494,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { + // FIXME(field_projections): We should not use `evaluate_obligation` in + // the trait solver. Doing so means we don't track overflow and cycles properly + // encountering query cycles instead. if let ty::Adt(def, args) = obligation.predicate.self_ty().skip_binder().kind() && let Some(FieldInfo { base, ty, .. }) = def.field_representing_type_info(self.tcx(), args) From 16ede108f08f85dbbac01dc4cc3318f092d1893f Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:42:42 +0200 Subject: [PATCH 11/15] library: prune allowed lints --- library/alloc/src/alloc.rs | 1 - library/alloc/src/lib.rs | 1 - library/alloctests/lib.rs | 1 - library/core/src/alloc/mod.rs | 2 +- library/core/src/lib.rs | 1 - library/core/src/num/int_macros.rs | 3 --- library/core/src/panic/panic_info.rs | 2 +- library/core/src/str/mod.rs | 1 - library/std/src/alloc.rs | 1 - library/std/src/env.rs | 2 +- library/std/src/lib.rs | 31 +++++++++++++--------------- library/std/src/num/f32.rs | 2 +- library/std/src/num/f64.rs | 2 +- 13 files changed, 19 insertions(+), 31 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 0846063cbc175..f921bc292568d 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -663,7 +663,6 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { #[cfg(not(no_global_oom_handling))] #[doc(hidden)] -#[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] pub mod __alloc_error_handler { // called via generated `__rust_alloc_error_handler` if there is no diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index acdc22ac5b331..664e3a4b1e218 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -58,7 +58,6 @@ #![allow(unused_features)] #![allow(incomplete_features)] -#![allow(unused_attributes)] #![expect(clippy::partialeq_ne_impl, reason = "we need to implement ne for a lot of alloc types")] #![stable(feature = "alloc", since = "1.36.0")] #![doc( diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 3c26ecf9875e2..50c58092bd41a 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -1,5 +1,4 @@ #![cfg(test)] -#![allow(unused_attributes)] #![unstable(feature = "alloctests", issue = "none")] #![no_std] // Lints: diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 6069c468f96e4..9acd3dd12a64c 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -15,7 +15,7 @@ pub use self::layout::Layout; note = "Name does not follow std convention, use LayoutError", suggestion = "LayoutError" )] -#[allow(deprecated, deprecated_in_future)] +#[allow(deprecated)] pub use self::layout::LayoutErr; #[stable(feature = "alloc_layout_error", since = "1.50.0")] pub use self::layout::LayoutError; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c215560122022..d7d8d32ed88e7 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -367,7 +367,6 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn, ambiguous_glob_reexports, - deprecated_in_future, unreachable_pub, // FIXME: stdach is a submodule so clippy lints should be fixed (and ideally enforced) there clippy::all, diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index bb37a734824fa..4cbd012e0021b 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2485,7 +2485,6 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[allow(unused_attributes)] #[inline] pub const fn wrapping_abs(self) -> Self { if self.is_negative() { @@ -2978,7 +2977,6 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[allow(unused_attributes)] pub const fn overflowing_neg(self) -> (Self, bool) { if intrinsics::unlikely(self == Self::MIN) { (Self::MIN, true) @@ -3630,7 +3628,6 @@ macro_rules! int_impl { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] - #[allow(unused_attributes)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index ee22521cb014c..a5448b39ad7c0 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -106,7 +106,7 @@ impl<'a> PanicInfo<'a> { /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload #[deprecated(since = "1.81.0", note = "this never returns anything useful")] #[stable(feature = "panic_hooks", since = "1.10.0")] - #[allow(deprecated, deprecated_in_future)] + #[allow(deprecated)] pub fn payload(&self) -> &(dyn crate::any::Any + Send) { struct NoPayload; &NoPayload diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index cc96e51d83393..99eb935cb2715 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -510,7 +510,6 @@ impl str { #[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")] #[must_use] #[inline(always)] - #[allow(unused_attributes)] pub const fn as_bytes(&self) -> &[u8] { // SAFETY: const sound because we transmute two types with the same layout unsafe { mem::transmute(self) } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 558ab0f2fc66d..8e0143c137b5e 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -444,7 +444,6 @@ pub fn rust_oom(layout: Layout) -> ! { #[cfg(not(test))] #[doc(hidden)] -#[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] pub mod __default_lib_allocator { use super::Layout; diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 762ad071e967c..07645debe82be 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -592,7 +592,7 @@ impl fmt::Display for JoinPathsError { #[stable(feature = "env", since = "1.0.0")] impl Error for JoinPathsError { - #[allow(deprecated, deprecated_in_future)] + #[allow(deprecated)] fn description(&self) -> &str { self.inner.description() } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 3f853df52bc53..acc8cdfc8281d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -244,7 +244,6 @@ #![warn(unreachable_pub)] #![warn(missing_debug_implementations)] #![allow(explicit_outlives_requirements)] -#![allow(unused_lifetimes)] #![allow(internal_features)] #![deny(implicit_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] @@ -539,24 +538,24 @@ pub use core::future; #[stable(feature = "core_hint", since = "1.27.0")] pub use core::hint; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::i8; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::i16; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::i32; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::i64; #[stable(feature = "i128", since = "1.26.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::i128; #[stable(feature = "rust1", since = "1.0.0")] pub use core::intrinsics; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::isize; #[stable(feature = "rust1", since = "1.0.0")] pub use core::iter; @@ -577,24 +576,24 @@ pub use core::range; #[stable(feature = "rust1", since = "1.0.0")] pub use core::result; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::u8; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::u16; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::u32; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::u64; #[stable(feature = "i128", since = "1.26.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::u128; #[unstable(feature = "unsafe_binders", issue = "130516")] pub use core::unsafe_binder; #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::usize; #[stable(feature = "rust1", since = "1.0.0")] @@ -740,7 +739,7 @@ pub mod alloc; mod panicking; #[path = "../../backtrace/src/lib.rs"] -#[allow(dead_code, unused_attributes, implicit_provenance_casts, unsafe_op_in_unsafe_fn)] +#[allow(implicit_provenance_casts, unsafe_op_in_unsafe_fn)] #[allow(clippy::len_zero, clippy::needless_borrow, clippy::filter_map_next)] // FIXME mod backtrace_rs; @@ -760,12 +759,10 @@ pub use core::concat_bytes; #[unstable(feature = "derive_macro_global_path", issue = "154645")] pub use core::derive; #[stable(feature = "matches_macro", since = "1.42.0")] -#[allow(deprecated, deprecated_in_future)] pub use core::matches; #[stable(feature = "core_primitive", since = "1.43.0")] pub use core::primitive; #[stable(feature = "todo_macro", since = "1.40.0")] -#[allow(deprecated, deprecated_in_future)] pub use core::todo; // Re-export built-in macros defined through core. #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] @@ -776,7 +773,7 @@ pub use core::{ }; // Re-export macros defined in core. #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] +#[expect(deprecated, reason = "`try! macro")] pub use core::{ assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, r#try, unimplemented, unreachable, write, writeln, diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index b89c71dd1abe1..5792d236b4e89 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -13,7 +13,7 @@ #![allow(missing_docs)] #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::f32::{ DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, MIN_EXP, MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, consts, diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index c3f5d8cca6014..8ca38cc0be69e 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -13,7 +13,7 @@ #![allow(missing_docs)] #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future, clippy::legacy_numeric_constants)] +#[allow(deprecated, clippy::legacy_numeric_constants)] pub use core::f64::{ DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, MIN_EXP, MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, consts, From 9fecc5aefe59d203ed2111b3cdf2c3f26138347b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 22 Sep 2026 08:52:22 +1000 Subject: [PATCH 12/15] Clean up diagnostic hashing `DiagInner` impls `PartialEq` and `Hash`, as you'd expect for storing it in a hash table. But there's a couple of strange things. - We only store the hash value of the `DiagInner` to do deduplication, not the `DiagInner` itself, which means the `PartialEq` impl is unused. - The `Hash` impl only considers some of the fields. Some of the ignored fields are clearly deliberate (there are comments) but for some it is unclear if it is deliberate. This commit: - Removes the unused `PartialEq` impl. - Inlines and removes `keys` now that it's not needed for `PartialEq`. - Uses struct deconstruction to ensure no fields can be accidentally ignored. I have preserved existing behaviour by assuming that all the ignored fields are supposed to be ignored. - Renames `hash` as an inherent method `dedup_hash` to indicate that it's not a typical hash function, and simplifies it to just return `Hash128` instead of being generic. - Replaces the unnecessary `collect` on `args` with `as_slice`. - Improves the comment on `emitted_diagnostics`. --- compiler/rustc_errors/src/diagnostic.rs | 71 ++++++++++--------------- compiler/rustc_errors/src/lib.rs | 13 ++--- 2 files changed, 34 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 9a12d6d53b6e6..729569fd5f5d1 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,13 +1,15 @@ use std::borrow::Cow; use std::fmt::{self, Debug}; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::ops::{Deref, DerefMut}; use std::panic; use std::path::PathBuf; use std::thread::panicking; use rustc_ast::attr::version::RustcVersion; -use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg}; +use rustc_data_structures::stable_hash::StableHasher; +use rustc_error_messages::{DiagArgMap, DiagArgName, IntoDiagArg}; +use rustc_hashes::Hash128; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; use rustc_span::{DUMMY_SP, Span, Spanned, Symbol}; @@ -305,46 +307,31 @@ impl DiagInner { } } - /// Fields used for Hash, and PartialEq trait. - fn keys( - &self, - ) -> ( - &Level, - &[(DiagMessage, Style)], - &Option, - &MultiSpan, - &[Subdiag], - &Suggestions, - Vec<(&DiagArgName, &DiagArgValue)>, - &Option, - ) { - ( - &self.level, - &self.messages, - &self.code, - &self.span, - &self.children, - &self.suggestions, - self.args.iter().collect(), - // omit self.sort_span - &self.is_lint, - // omit self.emitted_at - ) - } -} - -impl Hash for DiagInner { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - self.keys().hash(state); - } -} - -impl PartialEq for DiagInner { - fn eq(&self, other: &Self) -> bool { - self.keys() == other.keys() + /// Hash used to determine if two diagnostics are the same. Used by + /// `DiagCtxtInner::emitted_diagnostics`. Some fields are ignored for the hash. + pub(crate) fn dedup_hash(&self) -> Hash128 { + // Deconstruct to ensure all fields are considered. + let DiagInner { + level, + messages, + code, + lint_id: _, // ignore + span, + children, + suggestions, + args, + sort_span: _, // ignore + is_lint, + long_ty_path: _, // ignore + emitted_at: _, // ignore + } = self; + + let hashed_parts = + (level, messages, code, span, children, suggestions, args.as_slice(), is_lint); + + let mut hasher = StableHasher::new(); + hashed_parts.hash(&mut hasher); + hasher.finish() } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 30791a51f7644..68e10802e21c5 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -325,8 +325,10 @@ struct DiagCtxtInner { emitted_diagnostic_codes: FxIndexSet, /// This set contains a hash of every diagnostic that has been emitted by - /// this `DiagCtxt`. These hashes is used to avoid emitting the same error - /// twice. + /// this `DiagCtxt`. These hashes are used to avoid emitting the same error + /// twice. (Because we don't store the diagnostics themselves, two + /// different diagnostics with the same hash value will be considered + /// equivalent. Such collisions should be vanishingly rare...) emitted_diagnostics: FxHashSet, /// We only want to emit `recursion_depth_exceeding_limit` once per @@ -1301,12 +1303,7 @@ impl DiagCtxtInner { self.emitted_diagnostic_codes.insert(code); } - let already_emitted = { - let mut hasher = StableHasher::new(); - diagnostic.hash(&mut hasher); - let diagnostic_hash = hasher.finish(); - !self.emitted_diagnostics.insert(diagnostic_hash) - }; + let already_emitted = !self.emitted_diagnostics.insert(diagnostic.dedup_hash()); let is_error = diagnostic.is_error(); let is_lint = diagnostic.is_lint.is_some(); From 7eea74898ef0eda494e2276ab88bf2354ddc1cac Mon Sep 17 00:00:00 2001 From: Flakebi Date: Tue, 1 Sep 2026 09:40:37 +0200 Subject: [PATCH 13/15] Add address_space and byref to abi PassMode::Indirect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both will be used by the amdgpu target to implement the `gpu-kernel` ABI. `address_space` specifies the address space of an indirect argument. `AmdgpuKernelArg` translates to LLVM’s byref, which is similar to on_stack/byval, however, there is no extra copy made, the pointer may not point to the stack but can point to some other address space, and the passed argument should not be modified. byval and byref are mutually exclusive, so change on_stack to an enum with the new states, Pointer (none), OnStack and AmdgpuKernelArg. --- compiler/rustc_abi/src/layout/ty.rs | 4 +- .../src/abi/pass_mode.rs | 24 ++-- .../src/abi/returning.rs | 17 +-- compiler/rustc_codegen_gcc/src/abi.rs | 33 ++++- compiler/rustc_codegen_llvm/src/abi.rs | 111 +++++++++++++--- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/mod.rs | 4 + compiler/rustc_codegen_ssa/src/mir/block.rs | 48 ++++--- compiler/rustc_codegen_ssa/src/mir/mod.rs | 16 ++- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 5 + .../src/deduce_param_attrs.rs | 2 +- compiler/rustc_public/src/abi.rs | 18 ++- .../src/unstable/convert/stable/abi.rs | 35 +++-- compiler/rustc_target/src/callconv/mod.rs | 125 ++++++++++++++---- compiler/rustc_target/src/callconv/x86.rs | 5 +- compiler/rustc_target/src/callconv/xtensa.rs | 6 +- compiler/rustc_ty_utils/src/abi.rs | 14 +- tests/assembly-llvm/tail-call-indirect.rs | 6 +- tests/ui-fulldeps/rustc_public/check_abi.rs | 8 +- .../rustc_public/check_abi_cast.rs | 4 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 3 +- tests/ui/abi/c-zst.s390x-linux.stderr | 3 +- tests/ui/abi/c-zst.sparc-linux.stderr | 3 +- tests/ui/abi/c-zst.sparc-none.stderr | 3 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 3 +- .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 3 +- tests/ui/abi/debug.generic.stderr | 6 +- tests/ui/abi/debug.loongarch64.stderr | 6 +- tests/ui/abi/debug.riscv64.stderr | 6 +- tests/ui/abi/pass-indirectly-attr.rs | 2 +- tests/ui/abi/pass-indirectly-attr.stderr | 3 +- .../pass-by-value-abi.aarch64.stderr | 3 +- tests/ui/c-variadic/pass-by-value-abi.rs | 8 +- .../pass-by-value-abi.x86_64.stderr | 9 +- tests/ui/explicit-tail-calls/indirect.rs | 10 +- 35 files changed, 406 insertions(+), 151 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index e51255dc5963f..b8928aecf0cc5 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -233,8 +233,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { } /// If this method returns `true`, then this type should always have a `PassMode` of - /// `Indirect { on_stack: false, .. }` when being used as the argument type of a function with a - /// non-Rustic ABI (this is true for structs annotated with the + /// `Indirect { mode: IndirectMode::Pointer, .. }` when being used as the argument type of a + /// function with a non-Rustic ABI (this is true for structs annotated with the /// `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute). /// /// This is used to replicate some of the behaviour of C array-to-pointer decay; however unlike diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index 1c552ca1a9c32..48ffc43c5cfa1 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs @@ -3,7 +3,7 @@ use cranelift_codegen::ir::ArgumentPurpose; use rustc_abi::{Reg, RegKind}; use rustc_target::callconv::{ - ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, PassMode, + ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, IndirectMode, PassMode, }; use smallvec::{SmallVec, smallvec}; @@ -126,8 +126,12 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { assert_eq!(pad_i32_count, 0, "padding support not yet implemented"); cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect() } - PassMode::Indirect { attrs, meta_attrs: None, on_stack } => { - if on_stack { + PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode } => { + assert!( + mode != IndirectMode::AmdgpuKernelArg, + "unsupported amdgpu kernel argument" + ); + if mode == IndirectMode::OnStack { // Abi requires aligning struct size to pointer size let size = self.layout.size.align_to(tcx.data_layout.pointer_align().abi); let size = u32::try_from(size.bytes()).unwrap(); @@ -139,8 +143,8 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { smallvec![apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)] } } - PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { - assert!(!on_stack); + PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), address_space: _, mode } => { + assert!(mode == IndirectMode::Pointer); smallvec![ apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs), apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), meta_attrs), @@ -184,8 +188,8 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { None, cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect(), ), - PassMode::Indirect { attrs, meta_attrs: None, on_stack } => { - assert!(!on_stack); + PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode } => { + assert!(mode == IndirectMode::Pointer); ( Some(apply_attrs_to_abi_param( AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn), @@ -194,7 +198,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { vec![], ) } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { unreachable!("unsized return value") } } @@ -324,7 +328,7 @@ pub(super) fn cvalue_for_param<'tcx>( PassMode::Cast { ref cast, .. } => { from_casted_value(fx, &block_params, arg_abi.layout, cast) } - PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode: _ } => { assert_eq!(block_params.len(), 1, "{:?}", block_params); if let Some(pointee_align) = attrs.pointee_align && pointee_align < arg_abi.layout.align.abi @@ -342,7 +346,7 @@ pub(super) fn cvalue_for_param<'tcx>( CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout) } } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { assert_eq!(block_params.len(), 2, "{:?}", block_params); CValue::by_ref_unsized(Pointer::new(block_params[0]), block_params[1], arg_abi.layout) } diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index 36087f96dd776..7f4ee9435b506 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -17,12 +17,12 @@ pub(super) fn codegen_return_param<'tcx>( let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.ret.layout.ty); (super::make_local_place(fx, RETURN_PLACE, fx.fn_abi.ret.layout, is_ssa), smallvec![]) } - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type); (CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.ret.layout), smallvec![ret_param]) } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { unreachable!("unsized return value") } }; @@ -50,7 +50,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( ) { let (ret_temp_place, return_ptr) = match ret_arg_abi.mode { PassMode::Ignore => (None, None), - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => { if let Some(ret_ptr) = ret_place.try_to_ptr() { // This is an optimization to prevent unnecessary copies of the return value when // the return place is already a memory place as opposed to a register. @@ -61,7 +61,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( (Some(place), Some(place.to_ptr().get_addr(fx))) } } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { unreachable!("unsized return value") } PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => (None, None), @@ -86,14 +86,14 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); ret_place.write_cvalue(fx, result); } - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => { if let Some(ret_temp_place) = ret_temp_place { // If ret_temp_place is None, it is not necessary to copy the return value. let ret_temp_value = ret_temp_place.to_cvalue(fx); ret_place.write_cvalue(fx, ret_temp_value); } } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { unreachable!("unsized return value") } } @@ -102,10 +102,11 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( /// Codegen a return instruction with the right return value(s) if any. pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { match fx.fn_abi.ret.mode { - PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { + PassMode::Ignore + | PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => { fx.bcx.ins().return_(&[]); } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { unreachable!("unsized return value") } PassMode::Direct(_) => { diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 6a05f1cbbeef1..b5834ca57ebe1 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::{Session, config}; use rustc_span::bug; -use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, IndirectMode, PassMode}; #[cfg(feature = "master")] use rustc_target::spec::Arch; @@ -178,19 +178,42 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { let ty = cast.gcc_type(cx); apply_attrs(ty, &cast.attrs, argument_tys.len()) } - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => { + PassMode::Indirect { + attrs: _, + meta_attrs: None, + address_space: _, + mode: IndirectMode::OnStack, + } => { // This is a "byval" argument, so we don't apply the `restrict` attribute on it. on_stack_param_indices.insert(argument_tys.len()); arg.layout.gcc_type(cx) } + PassMode::Indirect { + attrs: _, + meta_attrs: None, + address_space: _, + mode: IndirectMode::AmdgpuKernelArg, + } => { + unimplemented!("unsupported amdgpu kernel argument") + } PassMode::Direct(attrs) => { apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()) } - PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::Pointer, + } => { apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len()) } - PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { - assert!(!on_stack); + PassMode::Indirect { + attrs, + meta_attrs: Some(meta_attrs), + address_space: _, + mode, + } => { + assert!(mode == IndirectMode::Pointer); // Construct the type of a (wide) pointer to `ty`, and pass its two fields. // Any two ABI-compatible unsized types have the same metadata type and // moreover the same metadata value leads to the same dynamic size and diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index dce8db6841b7f..e16f34483a0c5 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_session::{Session, config}; use rustc_span::bug; use rustc_target::callconv::{ - ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, + ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, IndirectMode, PassMode, }; use rustc_target::spec::{Arch, SanitizerSet}; use smallvec::SmallVec; @@ -243,12 +243,12 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { match &self.mode { PassMode::Ignore => {} // Sized indirect arguments - PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode: _ } => { let align = attrs.pointee_align.unwrap_or(self.layout.align.abi); OperandValue::Ref(PlaceValue::new_sized(val, align)).store(bx, dst); } // Unsized indirect arguments cannot be stored - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { bug!("unsized `ArgAbi` cannot be stored"); } PassMode::Cast { cast, pad_i32_count: _ } => { @@ -304,11 +304,11 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { PassMode::Pair(..) => { OperandValue::Pair(next(), next()).store(bx, dst); } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { bug!("unsized `ArgAbi` cannot be stored"); } PassMode::Direct(_) - | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } + | PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } | PassMode::Cast { .. } => { let next_arg = next(); self.store(bx, next_arg, dst); @@ -369,8 +369,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx), PassMode::Cast { cast, pad_i32_count: _ } => cast.llvm_type(cx), - PassMode::Indirect { .. } => { - llargument_tys.push(cx.type_ptr()); + PassMode::Indirect { address_space, .. } => { + let ty = if let Some(address_space) = address_space { + cx.type_ptr_ext(*address_space) + } else { + cx.type_ptr() + }; + llargument_tys.push(ty); cx.type_void() } }; @@ -395,7 +400,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true)); continue; } - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { // Construct the type of a (wide) pointer to `ty`, and pass its two fields. // Any two ABI-compatible unsized types have the same metadata type and // moreover the same metadata value leads to the same dynamic size and @@ -406,7 +411,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true)); continue; } - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => cx.type_ptr(), + PassMode::Indirect { attrs: _, meta_attrs: None, address_space, mode: _ } => { + if let Some(address_space) = address_space { + cx.type_ptr_ext(*address_space) + } else { + cx.type_ptr() + } + } PassMode::Cast { cast, pad_i32_count } => { // Add padding. llargument_tys.extend(std::iter::repeat_n( @@ -496,8 +507,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { apply_range_attr(llvm::AttributePlace::ReturnValue, scalar); } } - PassMode::Indirect { attrs, meta_attrs: _, on_stack } => { - assert!(!on_stack); + PassMode::Indirect { attrs, meta_attrs: _, address_space: _, mode } => { + assert!(*mode == IndirectMode::Pointer); let i = apply(attrs); let sret = llvm::CreateStructRetAttr( cx.llcx, @@ -523,7 +534,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { for arg in self.args.iter() { match &arg.mode { PassMode::Ignore => {} - PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => { + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::OnStack, + } => { let i = apply(attrs); let byval = llvm::CreateByValAttr( cx.llcx, @@ -531,13 +547,31 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { ); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]); } + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::AmdgpuKernelArg, + } => { + let i = apply(attrs); + let byref = llvm::CreateByRefAttr( + cx.llcx, + cx.type_array(cx.type_i8(), arg.layout.size.bytes()), + ); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byref]); + } PassMode::Direct(attrs) => { let i = apply(attrs); if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar); } } - PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::Pointer, + } => { let i = apply(attrs); if cx.sess().opts.optimize != config::OptLevel::No { attributes::apply_to_llfn( @@ -547,8 +581,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { ); } } - PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { - assert!(!on_stack); + PassMode::Indirect { + attrs, + meta_attrs: Some(meta_attrs), + address_space: _, + mode, + } => { + assert!(*mode == IndirectMode::Pointer); apply(attrs); apply(meta_attrs); } @@ -626,8 +665,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Direct(attrs) => { attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite); } - PassMode::Indirect { attrs, meta_attrs: _, on_stack } => { - assert!(!on_stack); + PassMode::Indirect { attrs, meta_attrs: _, address_space: _, mode } => { + assert!(*mode == IndirectMode::Pointer); let i = apply(bx.cx, attrs); let sret = llvm::CreateStructRetAttr( bx.cx.llcx, @@ -647,7 +686,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { for arg in self.args.iter() { match &arg.mode { PassMode::Ignore => {} - PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => { + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::OnStack, + } => { let i = apply(bx.cx, attrs); let byval = llvm::CreateByValAttr( bx.cx.llcx, @@ -659,11 +703,38 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { &[byval], ); } + PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::AmdgpuKernelArg, + } => { + let i = apply(bx.cx, attrs); + let byref = llvm::CreateByRefAttr( + bx.cx.llcx, + bx.cx.type_array(bx.cx.type_i8(), arg.layout.size.bytes()), + ); + attributes::apply_to_callsite( + callsite, + llvm::AttributePlace::Argument(i), + &[byref], + ); + } PassMode::Direct(attrs) - | PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { + | PassMode::Indirect { + attrs, + meta_attrs: None, + address_space: _, + mode: IndirectMode::Pointer, + } => { apply(bx.cx, attrs); } - PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack: _ } => { + PassMode::Indirect { + attrs, + meta_attrs: Some(meta_attrs), + address_space: _, + mode: _, + } => { apply(bx.cx, attrs); apply(bx.cx, meta_attrs); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 52218bfa336b8..07381745afe84 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2016,6 +2016,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute; pub(crate) fn LLVMRustCreateDereferenceableOrNullAttr(C: &Context, bytes: u64) -> &Attribute; pub(crate) fn LLVMRustCreateByValAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute; + pub(crate) fn LLVMRustCreateByRefAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute; pub(crate) fn LLVMRustCreateStructRetAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute; pub(crate) fn LLVMRustCreateElementTypeAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute; pub(crate) fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute; diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 5452f4abc5c33..89e4d60656d34 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -122,6 +122,10 @@ pub(crate) fn CreateByValAttr<'ll>(llcx: &'ll Context, ty: &'ll Type) -> &'ll At unsafe { LLVMRustCreateByValAttr(llcx, ty) } } +pub(crate) fn CreateByRefAttr<'ll>(llcx: &'ll Context, ty: &'ll Type) -> &'ll Attribute { + unsafe { LLVMRustCreateByRefAttr(llcx, ty) } +} + pub(crate) fn CreateStructRetAttr<'ll>(llcx: &'ll Context, ty: &'ll Type) -> &'ll Attribute { unsafe { LLVMRustCreateStructRetAttr(llcx, ty) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 6b0def4ffa182..f99009a0f4243 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt}; use rustc_session::config::OptLevel; use rustc_span::{Span, Spanned, bug, span_bug}; -use rustc_target::callconv::{ArgAbi, ArgAttributes, CastTarget, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, ArgAttributes, CastTarget, FnAbi, IndirectMode, PassMode}; use tracing::{debug, info}; use super::operand::OperandRef; @@ -1257,7 +1257,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (args, None) }; - // Special logic for tail calls with `PassMode::Indirect { on_stack: false, .. }` arguments. + // Special logic for tail calls with `PassMode::Indirect { mode: IndirectMode::Pointer, .. }` arguments. // // Normally an indirect argument that is allocated in the caller's stack frame // would be passed as a pointer into the callee's stack frame. @@ -1282,10 +1282,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut tail_call_temporaries = vec![]; if kind == CallKind::Tail { tail_call_temporaries = vec![None; first_args.len()]; - // Copy the arguments that use `PassMode::Indirect { on_stack: false , ..}` + // Copy the arguments that use `PassMode::Indirect { mode: IndirectMode::Pointer , ..}` // to temporary stack allocations. See the comment above. for (i, arg) in first_args.iter().enumerate() { - if !matches!(fn_abi.args[i].mode, PassMode::Indirect { on_stack: false, .. }) { + if !matches!( + fn_abi.args[i].mode, + PassMode::Indirect { mode: IndirectMode::Pointer, .. } + ) { continue; } @@ -1353,10 +1356,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - let by_move = if let PassMode::Indirect { on_stack: false, .. } = fn_abi.args[i].mode + let by_move = if let PassMode::Indirect { mode: IndirectMode::Pointer, .. } = + fn_abi.args[i].mode && kind == CallKind::Tail { - // Special logic for tail calls with `PassMode::Indirect { on_stack: false, .. }` arguments. + // Special logic for tail calls with `PassMode::Indirect { mode: IndirectMode::Pointer, .. }` arguments. // // Normally an indirect argument that is allocated in the caller's stack frame // would be passed as a pointer into the callee's stack frame. @@ -1977,14 +1981,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => bug!("codegen_argument: {:?} invalid for pair argument", op), }, - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => match op.val { - Ref(PlaceValue { llval: a, llextra: Some(b), .. }) => { - llargs.push(a); - llargs.push(b); - return; + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { + match op.val { + Ref(PlaceValue { llval: a, llextra: Some(b), .. }) => { + llargs.push(a); + llargs.push(b); + return; + } + _ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op), } - _ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op), - }, + } _ => {} } @@ -2014,7 +2020,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { PassMode::Ignore | PassMode::Pair(..) => unreachable!("handled above"), }, Ref(op_place_val) => match arg.mode { - PassMode::Indirect { attrs, on_stack, .. } => { + PassMode::Indirect { attrs, mode, .. } => { + if mode == IndirectMode::AmdgpuKernelArg { + bug!("{op:?} passed as amdgpu kernel argument with abi {arg:?}"); + } // For `foo(packed.large_field)`, and types with <4 byte alignment on x86, // alignment requirements may be higher than the type's alignment, so copy // to a higher-aligned alloca. @@ -2023,7 +2032,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => arg.layout.align.abi, }; // Copy to an alloca when the argument is neither by-val nor by-move. - if op_place_val.align < required_align || (!on_stack && !by_move) { + if op_place_val.align < required_align + || (mode == IndirectMode::Pointer && !by_move) + { let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); bx.lifetime_start(scratch.llval, arg.layout.size); op.store_with_annotation(bx, scratch.with_type(arg.layout)); @@ -2036,8 +2047,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => (op_place_val.llval, op_place_val.align, true), }, ZeroSized => match arg.mode { - PassMode::Indirect { on_stack, .. } => { - if on_stack { + PassMode::Indirect { mode, .. } => { + if mode == IndirectMode::AmdgpuKernelArg { + bug!("{op:?} passed as amdgpu kernel argument with abi {arg:?}"); + } + if mode == IndirectMode::OnStack { // It doesn't seem like any target can have `byval` ZSTs, so this assert // is here to replace a would-be untested codepath. bug!("ZST {op:?} passed on stack with abi {arg:?}"); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index b5cecf4b5c434..aefa8356536dc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::{Body, Local, UnwindTerminateReason, traversal}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, bug, span_bug}; -use rustc_target::callconv::{FnAbi, PassMode}; +use rustc_target::callconv::{FnAbi, IndirectMode, PassMode}; use tracing::{debug, instrument}; use crate::base; @@ -561,15 +561,21 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( match arg.mode { // Sized indirect arguments - PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode } => { // Don't copy an indirect argument to an alloca, the caller already put it // in a temporary alloca and gave it up. + // AmdgpuKernelArg/byref arguments must not be modified, so always create a + // local alloca for them. + // If the argument is underaligned, then we need to copy it to a higher-aligned + // alloca. // FIXME: lifetimes + let mut needs_alloca = mode == IndirectMode::AmdgpuKernelArg; if let Some(pointee_align) = attrs.pointee_align && pointee_align < arg.layout.align.abi { - // ...unless the argument is underaligned, then we need to copy it to - // a higher-aligned alloca. + needs_alloca = true; + } + if needs_alloca { let tmp = PlaceRef::alloca(bx, arg.layout); bx.store_fn_arg(arg, &mut llarg_idx, tmp); LocalRef::Place(tmp) @@ -580,7 +586,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } // Unsized indirect arguments - PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => { // As the storage for the indirect argument lives during // the whole function call, we just copy the wide pointer. let llarg = bx.get_param(llarg_idx); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 161b5bdb952d3..bc8fa60b66a52 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -480,6 +480,11 @@ extern "C" LLVMAttributeRef LLVMRustCreateByValAttr(LLVMContextRef C, return wrap(Attribute::getWithByValType(*unwrap(C), unwrap(Ty))); } +extern "C" LLVMAttributeRef LLVMRustCreateByRefAttr(LLVMContextRef C, + LLVMTypeRef Ty) { + return wrap(Attribute::getWithByRefType(*unwrap(C), unwrap(Ty))); +} + extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTypeRef Ty) { return wrap(Attribute::getWithStructRetType(*unwrap(C), unwrap(Ty))); diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index 5bba125aefc58..8814670ca4300 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -135,7 +135,7 @@ impl<'tcx> Visitor<'tcx> for DeduceParamAttrs { } // Like a call, but more conservative because the backend may introduce writes to an - // argument if the argument is passed as `PassMode::Indirect { on_stack: false, ... }`. + // argument if the argument is passed as `PassMode::Indirect { mode: IndirectMode::Pointer, ... }`. TerminatorKind::TailCall { .. } => { for usage in self.usage.iter_mut() { *usage |= UsageSummary::MUTATE; diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 67d609c780c42..72387fce19797 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -41,6 +41,19 @@ pub struct ArgAbi { pub mode: PassMode, } +/// Different modes in which indirect arguments can be passed. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)] +pub enum IndirectMode { + /// Passed as a normal pointer, nothing special. + Pointer, + /// The value is placed at a fixed stack offset rather than passed as a regular pointer + /// argument. + OnStack, + /// Similar to `OnStack` except that the pointer does not necessarily point to the stack, no + /// extra copy is made, and the passed argument should not be modified. + AmdgpuKernelArg, +} + /// How a function argument should be passed in to the target function. /// /// The pass mode is determined by the platform's calling convention and the @@ -74,14 +87,13 @@ pub enum PassMode { /// Pass the argument indirectly via a pointer. /// /// The caller places the value in memory and passes a pointer to it. - /// When `on_stack` is true, the value is placed at a fixed stack offset - /// rather than passed as a regular pointer argument. Indirect { attrs: ArgAttributes, /// Attributes for the metadata pointer (vtable or length) of unsized arguments. /// Only present for unsized types (e.g., `dyn Trait`, `[T]`). meta_attrs: Option, - on_stack: bool, + address_space: Option, + mode: IndirectMode, }, } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 3c268a6dd23a4..1ac0b706ed091 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -11,9 +11,9 @@ use rustc_target::callconv; use crate::IndexedVal; use crate::abi::{ AddressSpace, ArgAbi, ArgAttributes, ArgExtension, CallConvention, CastTarget, FieldsShape, - FloatLength, FnAbi, IntegerLength, IntegerType, Layout, LayoutShape, NumScalableVectors, - PassMode, Primitive, Reg, RegKind, ReprFlags, ReprOptions, Scalar, TagEncoding, TyAndLayout, - Uniform, ValueRepr, VariantFields, VariantsShape, WrappingRange, + FloatLength, FnAbi, IndirectMode, IntegerLength, IntegerType, Layout, LayoutShape, + NumScalableVectors, PassMode, Primitive, Reg, RegKind, ReprFlags, ReprOptions, Scalar, + TagEncoding, TyAndLayout, Uniform, ValueRepr, VariantFields, VariantsShape, WrappingRange, }; use crate::compiler_interface::BridgeTys; use crate::target::MachineSize as Size; @@ -155,6 +155,22 @@ impl<'tcx> Stable<'tcx> for CanonAbi { } } +impl<'tcx> Stable<'tcx> for callconv::IndirectMode { + type T = IndirectMode; + + fn stable<'cx>( + &self, + _tables: &mut Tables<'cx, BridgeTys>, + _cx: &CompilerCtxt<'cx, BridgeTys>, + ) -> Self::T { + match self { + callconv::IndirectMode::Pointer => IndirectMode::Pointer, + callconv::IndirectMode::OnStack => IndirectMode::OnStack, + callconv::IndirectMode::AmdgpuKernelArg => IndirectMode::AmdgpuKernelArg, + } + } +} + impl<'tcx> Stable<'tcx> for callconv::PassMode { type T = PassMode; @@ -172,11 +188,14 @@ impl<'tcx> Stable<'tcx> for callconv::PassMode { callconv::PassMode::Cast { pad_i32_count, cast } => { PassMode::Cast { pad_i32_count: *pad_i32_count, cast: cast.stable(tables, cx) } } - callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect { - attrs: attrs.stable(tables, cx), - meta_attrs: meta_attrs.map(|a| a.stable(tables, cx)), - on_stack: *on_stack, - }, + callconv::PassMode::Indirect { attrs, meta_attrs, address_space, mode } => { + PassMode::Indirect { + attrs: attrs.stable(tables, cx), + meta_attrs: meta_attrs.map(|a| a.stable(tables, cx)), + address_space: address_space.stable(tables, cx), + mode: mode.stable(tables, cx), + } + } } } } diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 1ac6168035085..edc23b6c50b45 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -36,6 +36,25 @@ mod x86_win32; mod x86_win64; mod xtensa; +/// Different modes in which indirect arguments can be passed. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, StableHash)] +pub enum IndirectMode { + /// Passed as a normal pointer, nothing special. + Pointer, + /// The value should be passed at a fixed stack offset in accordance to + /// the ABI rather than passed using a pointer. This corresponds to the `byval` LLVM argument + /// attribute. The `byval` argument will use a byte array with the same size as the Rust type + /// (which ensures that padding is preserved and that we do not rely on LLVM's struct layout), + /// and will use the alignment specified in `attrs.pointee_align` (if `Some`) or the type's + /// alignment (if `None`). This means that the alignment will not always + /// match the Rust type's alignment; see documentation of `pass_by_stack_offset` for more info. + OnStack, + /// `AmdgpuKernelArg` behaves similar to `OnStack` except that the pointer does not necessarily + /// point to the stack, no extra copy is made, and the passed argument should not be modified. + /// This corresponds to the `byref` LLVM argument attribute. + AmdgpuKernelArg, +} + #[derive(Clone, PartialEq, Eq, Hash, Debug, StableHash)] pub enum PassMode { /// Ignore the argument. @@ -63,16 +82,17 @@ pub enum PassMode { /// The `meta_attrs` value, if any, is for the metadata (vtable or length) of an unsized /// argument. (This is the only mode that supports unsized arguments.) /// - /// `on_stack` defines that the value should be passed at a fixed stack offset in accordance to - /// the ABI rather than passed using a pointer. This corresponds to the `byval` LLVM argument - /// attribute. The `byval` argument will use a byte array with the same size as the Rust type - /// (which ensures that padding is preserved and that we do not rely on LLVM's struct layout), - /// and will use the alignment specified in `attrs.pointee_align` (if `Some`) or the type's - /// alignment (if `None`). This means that the alignment will not always - /// match the Rust type's alignment; see documentation of `pass_by_stack_offset` for more info. + /// `address_space` specifies if the pointer is in a special address space or the default one. /// - /// `on_stack` cannot be true for unsized arguments, i.e., when `meta_attrs` is `Some`. - Indirect { attrs: ArgAttributes, meta_attrs: Option, on_stack: bool }, + /// `mode` can be a special way to pass an argument indirectly. + /// `OnStack` and `AmdgpuKernelArg` cannot be used for unsized arguments, i.e., when + /// `meta_attrs` is `Some`. + Indirect { + attrs: ArgAttributes, + meta_attrs: Option, + address_space: Option, + mode: IndirectMode, + }, } impl PassMode { @@ -89,13 +109,23 @@ impl PassMode { PassMode::Cast { cast: c2, pad_i32_count: pad2 }, ) => c1.eq_abi(c2) && pad1 == pad2, ( - PassMode::Indirect { attrs: a1, meta_attrs: None, on_stack: s1 }, - PassMode::Indirect { attrs: a2, meta_attrs: None, on_stack: s2 }, - ) => a1.eq_abi(a2) && s1 == s2, + PassMode::Indirect { attrs: a1, meta_attrs: None, address_space: as1, mode: m1 }, + PassMode::Indirect { attrs: a2, meta_attrs: None, address_space: as2, mode: m2 }, + ) => a1.eq_abi(a2) && as1 == as2 && m1 == m2, ( - PassMode::Indirect { attrs: a1, meta_attrs: Some(e1), on_stack: s1 }, - PassMode::Indirect { attrs: a2, meta_attrs: Some(e2), on_stack: s2 }, - ) => a1.eq_abi(a2) && e1.eq_abi(e2) && s1 == s2, + PassMode::Indirect { + attrs: a1, + meta_attrs: Some(e1), + address_space: as1, + mode: m1, + }, + PassMode::Indirect { + attrs: a2, + meta_attrs: Some(e2), + address_space: as2, + mode: m2, + }, + ) => a1.eq_abi(a2) && as1 == as2 && e1.eq_abi(e2) && m1 == m2, _ => false, } } @@ -424,7 +454,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { let meta_attrs = layout.is_unsized().then_some(ArgAttributes::new()); - PassMode::Indirect { attrs, meta_attrs, on_stack: false } + PassMode::Indirect { attrs, meta_attrs, address_space: None, mode: IndirectMode::Pointer } } /// Pass this argument indirectly, by passing a (thin or wide) pointer to the argument instead. @@ -435,13 +465,31 @@ impl<'a, Ty> ArgAbi<'a, Ty> { PassMode::Direct(_) | PassMode::Pair(_, _) => { self.mode = Self::indirect_pass_mode(&self.layout); } - PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => { + PassMode::Indirect { + attrs: _, + meta_attrs: _, + address_space: _, + mode: IndirectMode::Pointer, + } => { // already indirect } _ => panic!("Tried to make {:?} indirect", self.mode), } } + /// Pass this argument indirectly, by passing a (thin or wide) pointer to the argument instead. + /// This is valid for both sized and unsized arguments. + #[track_caller] + pub fn make_indirect_addrspace(&mut self, addrspace: AddressSpace) { + self.make_indirect(); + match self.mode { + PassMode::Indirect { ref mut address_space, .. } => { + *address_space = Some(addrspace); + } + _ => unreachable!(), + } + } + /// Same as `make_indirect`, but for arguments that are ignored. Only needed for ABIs that pass /// ZSTs indirectly. #[track_caller] @@ -450,7 +498,12 @@ impl<'a, Ty> ArgAbi<'a, Ty> { PassMode::Ignore => { self.mode = Self::indirect_pass_mode(&self.layout); } - PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => { + PassMode::Indirect { + attrs: _, + meta_attrs: _, + address_space: _, + mode: IndirectMode::Pointer, + } => { // already indirect } _ => panic!("Tried to make {:?} indirect (expected `PassMode::Ignore`)", self.mode), @@ -477,8 +530,8 @@ impl<'a, Ty> ArgAbi<'a, Ty> { assert!(!self.layout.is_unsized(), "used byval ABI for unsized layout"); self.make_indirect(); match self.mode { - PassMode::Indirect { ref mut attrs, meta_attrs: _, ref mut on_stack } => { - *on_stack = true; + PassMode::Indirect { ref mut attrs, meta_attrs: _, address_space: _, ref mut mode } => { + *mode = IndirectMode::OnStack; // Some platforms, like 32-bit x86, change the alignment of the type when passing // `byval`. Account for that. @@ -492,6 +545,22 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } } + /// Pass this argument indirectly. + /// This corresponds to the `byref` LLVM argument attribute. + /// + /// `address_space` specifies the address space of the passed pointer. + pub fn pass_amdgpu_kernel_arg(&mut self, addrspace: Option) { + assert!(!self.layout.is_unsized(), "used amdgpu kernel arg ABI for unsized layout"); + self.make_indirect(); + match self.mode { + PassMode::Indirect { attrs: _, meta_attrs: _, ref mut address_space, ref mut mode } => { + *mode = IndirectMode::AmdgpuKernelArg; + *address_space = addrspace; + } + _ => unreachable!(), + } + } + pub fn extend_integer_width_to(&mut self, bits: u64) { // Only integers have signedness if let BackendRepr::Scalar(scalar) = self.layout.backend_repr @@ -545,11 +614,17 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } pub fn is_sized_indirect(&self) -> bool { - matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ }) + matches!( + self.mode, + PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } + ) } pub fn is_unsized_indirect(&self) -> bool { - matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ }) + matches!( + self.mode, + PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } + ) } pub fn is_ignore(&self) -> bool { @@ -851,7 +926,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { // Compute `Aggregate` ABI. let is_indirect_not_on_stack = - matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); + matches!(arg.mode, PassMode::Indirect { mode: IndirectMode::Pointer, .. }); assert!(is_indirect_not_on_stack); let size = arg.layout.size; @@ -962,7 +1037,7 @@ mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(ArgAbi<'_, usize>, 56); - static_assert_size!(FnAbi<'_, usize>, 80); + static_assert_size!(ArgAbi<'_, usize>, 64); + static_assert_size!(FnAbi<'_, usize>, 88); // tidy-alphabetical-end } diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index a1c59d885b7fc..3476f41e3bc75 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -200,12 +200,13 @@ pub(crate) fn fill_inregs<'a, Ty, C>( for arg in fn_abi.args.iter_mut() { let attrs = match arg.mode { - PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { + PassMode::Ignore + | PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => { continue; } PassMode::Direct(ref mut attrs) => attrs, PassMode::Pair(..) - | PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } + | PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } | PassMode::Cast { .. } => { unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode) } diff --git a/compiler/rustc_target/src/callconv/xtensa.rs b/compiler/rustc_target/src/callconv/xtensa.rs index 4dc9fad650636..49005adeb33c0 100644 --- a/compiler/rustc_target/src/callconv/xtensa.rs +++ b/compiler/rustc_target/src/callconv/xtensa.rs @@ -7,7 +7,7 @@ use rustc_abi::{BackendRepr, HasDataLayout, Size, TyAbiInterface}; -use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform}; +use crate::callconv::{ArgAbi, FnAbi, IndirectMode, Reg, Uniform}; use crate::spec::HasTargetSpec; const NUM_ARG_GPRS: u64 = 6; @@ -29,8 +29,8 @@ where classify_arg_ty(cx, arg, &mut arg_gprs_left, true); // Ret args cannot be passed via stack, we lower to indirect and let the backend handle the invisible reference match arg.mode { - super::PassMode::Indirect { attrs: _, meta_attrs: _, ref mut on_stack } => { - *on_stack = false; + super::PassMode::Indirect { attrs: _, meta_attrs: _, address_space: _, ref mut mode } => { + *mode = IndirectMode::Pointer; } _ => {} } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 55140d2c5458d..e8f9ded9562d5 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -12,7 +12,9 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{self, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized}; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, bug}; -use rustc_target::callconv::{AbiMap, ArgAbi, ArgAttribute, ArgAttributes, FnAbi, PassMode}; +use rustc_target::callconv::{ + AbiMap, ArgAbi, ArgAttribute, ArgAttributes, FnAbi, IndirectMode, PassMode, +}; use tracing::debug; pub(crate) fn provide(providers: &mut Providers) { @@ -444,15 +446,15 @@ fn fn_abi_sanity_check<'tcx>( // omitted entirely in the calling convention. assert!(arg.is_ignore()); } - if let PassMode::Indirect { on_stack, .. } = arg.mode + if let PassMode::Indirect { mode, .. } = arg.mode && spec_abi != ExternAbi::RustTail { - assert!(!on_stack, "rustic abi {spec_abi:?} shouldn't use on_stack"); + assert!(mode == IndirectMode::Pointer, "rust abi must use plain pointer mode"); } } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { assert_matches!( arg.mode, - PassMode::Indirect { on_stack: false, .. }, + PassMode::Indirect { mode: IndirectMode::Pointer, .. }, "the {spec_abi} ABI does not implement `#[rustc_pass_indirectly_in_non_rustic_abis]`" ); } @@ -506,9 +508,9 @@ fn fn_abi_sanity_check<'tcx>( // Indirect returns are arguments from an ABI perspective. fn_arg_attrs_sanity_check(attrs, false); } - PassMode::Indirect { meta_attrs: Some(meta_attrs), attrs, on_stack } => { + PassMode::Indirect { meta_attrs: Some(meta_attrs), attrs, address_space: _, mode } => { // With metadata. Must be unsized and not on the stack. - assert!(arg.layout.is_unsized() && !on_stack); + assert!(arg.layout.is_unsized() && *mode == IndirectMode::Pointer); // Also, must not be `extern` type. let tail = tcx.struct_tail_for_codegen(arg.layout.ty, cx.typing_env); if matches!(tail.kind(), ty::Foreign(..)) { diff --git a/tests/assembly-llvm/tail-call-indirect.rs b/tests/assembly-llvm/tail-call-indirect.rs index 2bc1743a9bafd..918283966b405 100644 --- a/tests/assembly-llvm/tail-call-indirect.rs +++ b/tests/assembly-llvm/tail-call-indirect.rs @@ -10,10 +10,10 @@ #![no_core] #![crate_type = "lib"] -// Test tail calls with `PassMode::Indirect { on_stack: false, .. }` arguments. +// Test tail calls with `PassMode::Indirect { mode: IndirectMode::Pointer, .. }` arguments. // -// Normally an indirect argument with `on_stack: false` would be passed as a pointer to the -// caller's stack frame. For tail calls, that would be unsound, because the caller's stack +// Normally an indirect argument with `mode: IndirectMode::Pointer` would be passed as a pointer to +// the caller's stack frame. For tail calls, that would be unsound, because the caller's stack // frame is overwritten by the callee's stack frame. // // The solution is to write the argument into the caller's argument place (stored somewhere further diff --git a/tests/ui-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index ed616cc4d9bb0..92d6f28f8fd8c 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -15,8 +15,8 @@ extern crate rustc_middle; extern crate rustc_public; use rustc_public::abi::{ - ArgAbi, ArgExtension, CallConvention, FieldsShape, IntegerLength, PassMode, Primitive, Scalar, - ValueRepr, VariantsShape, + ArgAbi, ArgExtension, CallConvention, FieldsShape, IndirectMode, IntegerLength, PassMode, + Primitive, Scalar, ValueRepr, VariantsShape, }; use rustc_public::mir::MirVisitor; use rustc_public::mir::mono::Instance; @@ -127,14 +127,14 @@ fn check_primitive(abi: &ArgAbi) { /// Check the return value: `Result`. fn check_result(abi: &ArgAbi) { assert!(abi.ty.kind().is_enum()); - let PassMode::Indirect { ref attrs, ref meta_attrs, on_stack } = abi.mode else { + let PassMode::Indirect { ref attrs, ref meta_attrs, address_space: _, mode } = abi.mode else { panic!("Expected PassMode::Indirect for Result, got: {:?}", abi.mode); }; // Indirect arguments have a pointee alignment (the pointer must be aligned). assert!(attrs.pointee_align().is_some()); // Result is a sized type, so no metadata pointer. assert!(meta_attrs.is_none()); - assert!(!on_stack); + assert!(mode == IndirectMode::Pointer); let layout = abi.layout.shape(); assert!(layout.is_sized()); assert_matches!(layout.fields, FieldsShape::Arbitrary { .. }); diff --git a/tests/ui-fulldeps/rustc_public/check_abi_cast.rs b/tests/ui-fulldeps/rustc_public/check_abi_cast.rs index 0bd4ac684066e..a54abdd5deeaf 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi_cast.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi_cast.rs @@ -23,7 +23,7 @@ use std::convert::TryFrom; use std::io::Write; use std::ops::ControlFlow; -use rustc_public::abi::{CallConvention, PassMode, RegKind}; +use rustc_public::abi::{CallConvention, IndirectMode, PassMode, RegKind}; use rustc_public::mir::mono::Instance; use rustc_public::{CrateDef, ItemKind}; @@ -147,7 +147,7 @@ fn test_abi_cast() -> ControlFlow<()> { } // Fourth TwoWords has no registers left → Indirect (on stack) assert!( - matches!(&abi.args[3].mode, PassMode::Indirect { on_stack: true, .. }), + matches!(&abi.args[3].mode, PassMode::Indirect { mode: IndirectMode::OnStack, .. }), "Expected arg 3 to be Indirect on stack, got: {:?}", abi.args[3].mode ); diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/c-zst.sparc-linux.stderr b/tests/ui/abi/c-zst.sparc-linux.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.sparc-linux.stderr +++ b/tests/ui/abi/c-zst.sparc-linux.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/c-zst.sparc-none.stderr b/tests/ui/abi/c-zst.sparc-none.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.sparc-none.stderr +++ b/tests/ui/abi/c-zst.sparc-none.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 302ffe1efc8b8..e5cad2199491b 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr index 6242d93b09534..1793674fa462a 100644 --- a/tests/ui/abi/debug.generic.stderr +++ b/tests/ui/abi/debug.generic.stderr @@ -446,7 +446,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], @@ -519,7 +520,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr index 176c68ecd4c7b..29ec7846101f1 100644 --- a/tests/ui/abi/debug.loongarch64.stderr +++ b/tests/ui/abi/debug.loongarch64.stderr @@ -446,7 +446,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], @@ -519,7 +520,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr index 176c68ecd4c7b..29ec7846101f1 100644 --- a/tests/ui/abi/debug.riscv64.stderr +++ b/tests/ui/abi/debug.riscv64.stderr @@ -446,7 +446,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], @@ -519,7 +520,8 @@ error: ABIs are not compatible ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/abi/pass-indirectly-attr.rs b/tests/ui/abi/pass-indirectly-attr.rs index 54aafc716587c..bb90b8354ea91 100644 --- a/tests/ui/abi/pass-indirectly-attr.rs +++ b/tests/ui/abi/pass-indirectly-attr.rs @@ -20,7 +20,7 @@ pub struct Type(u8); pub extern "C" fn extern_c(_: Type) {} //~^ ERROR fn_abi_of(extern_c) = FnAbi { //~| ERROR mode: Indirect -//~| ERROR on_stack: false, +//~| ERROR mode: Pointer, //~| ERROR conv: C, #[rustc_abi(debug)] diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr index efeec0d86982b..5821e6279bb85 100644 --- a/tests/ui/abi/pass-indirectly-attr.stderr +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -48,7 +48,8 @@ error: fn_abi_of(extern_c) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr index 45edd7bc0e0ee..c9e77ac941901 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(take_va_list) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/c-variadic/pass-by-value-abi.rs b/tests/ui/c-variadic/pass-by-value-abi.rs index bcca09e90438a..317840601c050 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.rs +++ b/tests/ui/c-variadic/pass-by-value-abi.rs @@ -27,9 +27,9 @@ use std::ffi::VaList; pub extern "C" fn take_va_list(_: VaList<'_>) {} //~^ ERROR fn_abi_of(take_va_list) = FnAbi { //[x86_64]~^^ ERROR mode: Indirect { -//[x86_64]~^^^ ERROR on_stack: false, +//[x86_64]~^^^ ERROR mode: Pointer, //[aarch64]~^^^^ ERROR mode: Indirect { -//[aarch64]~^^^^^ ERROR on_stack: false, +//[aarch64]~^^^^^ ERROR mode: Pointer, //[win]~^^^^^^ ERROR mode: Direct( #[cfg(all(target_arch = "x86_64", not(windows)))] @@ -37,11 +37,11 @@ pub extern "C" fn take_va_list(_: VaList<'_>) {} pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} //[x86_64]~^ ERROR fn_abi_of(take_va_list_sysv64) = FnAbi { //[x86_64]~^^ ERROR mode: Indirect { -//[x86_64]~^^^ ERROR on_stack: false, +//[x86_64]~^^^ ERROR mode: Pointer, #[cfg(all(target_arch = "x86_64", not(windows)))] #[rustc_abi(debug)] pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} //[x86_64]~^ ERROR: fn_abi_of(take_va_list_win64) = FnAbi { //[x86_64]~^^ ERROR mode: Indirect { -//[x86_64]~^^^ ERROR on_stack: false, +//[x86_64]~^^^ ERROR mode: Pointer, diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr index 1e203b93e66b3..04320a5312361 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -35,7 +35,8 @@ error: fn_abi_of(take_va_list) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], @@ -113,7 +114,8 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], @@ -193,7 +195,8 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { ), }, meta_attrs: None, - on_stack: false, + address_space: None, + mode: Pointer, }, }, ], diff --git a/tests/ui/explicit-tail-calls/indirect.rs b/tests/ui/explicit-tail-calls/indirect.rs index b3e2613efad25..71107ef420c35 100644 --- a/tests/ui/explicit-tail-calls/indirect.rs +++ b/tests/ui/explicit-tail-calls/indirect.rs @@ -25,17 +25,17 @@ #![feature(explicit_tail_calls)] #![expect(incomplete_features)] -// Test tail calls with `PassMode::Indirect { on_stack: false, .. }` arguments. +// Test tail calls with `PassMode::Indirect { mode: IndirectMode::Pointer, .. }` arguments. // -// Normally an indirect argument with `on_stack: false` would be passed as a pointer to the -// caller's stack frame. For tail calls, that would be unsound, because the caller's stack +// Normally an indirect argument with `mode: IndirectMode::Pointer` would be passed as a pointer to +// the caller's stack frame. For tail calls, that would be unsound, because the caller's stack // frame is overwritten by the callee's stack frame. // // The solution is to write the argument into the caller's argument place (stored somewhere further // up the stack), and forward that place. // A struct big enough that it is not passed via registers, so that the rust calling convention uses -// `Indirect { on_stack: false, .. }`. +// `Indirect { mode: IndirectMode::Pointer, .. }`. #[repr(C)] #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] pub struct Big([u64; 4]); @@ -79,7 +79,7 @@ fn main() { assert_eq!(update_in_caller(Big::default()), 0 + 2 + 3 + 4); assert_eq!(swapper(u8::MIN, u8::MAX), (u8::MAX, u8::MIN)); - // i128 uses `PassMode::Indirect { on_stack: false, .. }` on x86_64 MSVC. + // i128 uses `PassMode::Indirect { mode: IndirectMode::Pointer, .. }` on x86_64 MSVC. assert_eq!(swapper(i128::MIN, i128::MAX), (i128::MAX, i128::MIN)); assert_eq!(swapper(Big([1; 4]), Big([2; 4])), (Big([2; 4]), Big([1; 4]))); From 5152c4c95eacf728bb416040c063e5953bfc64c3 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Thu, 3 Sep 2026 09:21:39 +0200 Subject: [PATCH 14/15] Pre-commit amdgpu gpu-kernel ABI test --- tests/codegen-llvm/amdgpu-abi/struct-abi.rs | 133 ++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 tests/codegen-llvm/amdgpu-abi/struct-abi.rs diff --git a/tests/codegen-llvm/amdgpu-abi/struct-abi.rs b/tests/codegen-llvm/amdgpu-abi/struct-abi.rs new file mode 100644 index 0000000000000..bf51cbfa7f7a0 --- /dev/null +++ b/tests/codegen-llvm/amdgpu-abi/struct-abi.rs @@ -0,0 +1,133 @@ +//@ add-minicore +//@ compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 -Copt-level=3 +//@ needs-llvm-components: amdgpu +#![feature(no_core, abi_gpu_kernel)] +#![no_core] +#![allow(improper_gpu_kernel_arg)] + +extern crate minicore; +use minicore::num::Complex; + +// Tests from llvm-project/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl + +#[repr(C)] +pub struct SingleElementStructArg { + i: i32, +} + +#[repr(C)] +pub struct NestedSingleElementStructArg { + i: SingleElementStructArg, +} + +#[repr(C)] +pub struct StructArg { + i1: i32, + f: f32, + i2: i32, +} + +#[repr(C)] +pub struct StructPaddingArg { + i1: i8, + f: i64, +} + +#[repr(C)] +pub struct StructOfArraysArg { + i1: [i32; 2], + f1: f32, + i2: [i32; 4], + f2: [f32; 3], + i3: i32, +} + +#[repr(C)] +pub struct StructOfStructsArg { + i1: i32, + f1: f32, + s1: StructArg, + i2: i32, +} + +#[repr(C)] +pub union U { + b1: i32, + b2: f32, +} + +#[repr(C)] +pub struct SingleArrayElementStructArg { + i: [i32; 4], +} + +#[repr(C)] +pub struct SingleStructElementStructArgInner { + i: i32, + b: i64, +} + +#[repr(C)] +pub struct SingleStructElementStructArg { + s: SingleStructElementStructArgInner, +} + +#[repr(C)] +pub struct DifferentSizeTypePair { + l: i64, + i: i32, +} + +// CHECK: define amdgpu_kernel void @kernel_single_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_single_element_struct_arg(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_nested_single_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_nested_single_element_struct_arg( + _: NestedSingleElementStructArg, +) { +} + +// CHECK: define amdgpu_kernel void @kernel_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(12) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_struct_arg(_: StructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_struct_padding_arg(i8 noundef {{%.+}}, i64 noundef {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_struct_padding_arg(_: StructPaddingArg) {} + +// CHECK: define amdgpu_kernel void @kernel_struct_of_arrays_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(44) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_struct_of_arrays_arg(_: StructOfArraysArg) {} + +// CHECK: define amdgpu_kernel void @kernel_struct_of_structs_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(24) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_struct_of_structs_arg(_: StructOfStructsArg) {} + +// CHECK: define amdgpu_kernel void @test_kernel_union_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn test_kernel_union_arg(_: U) {} + +// CHECK: define amdgpu_kernel void @kernel_single_array_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(16) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_single_array_element_struct_arg(_: SingleArrayElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_single_struct_element_struct_arg(i32 noundef {{%.+}}, i64 noundef {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_single_struct_element_struct_arg( + _: SingleStructElementStructArg, +) { +} + +// CHECK: define amdgpu_kernel void @kernel_different_size_type_pair_arg(i64 noundef {{%.+}}, i32 noundef {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_different_size_type_pair_arg(_: DifferentSizeTypePair) {} + +// CHECK: define amdgpu_kernel void @kernel_complex(float noundef {{%.+}}, float noundef {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_complex(_: Complex) {} + +// CHECK: define amdgpu_kernel void @kernel_slice(ptr noalias nofree noundef nonnull readonly align 4 captures(none) {{%.+}}, i64 noundef range(i64 0, 2305843009213693952) {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_slice(_: &[u32]) {} From 09e54da8abe7c940b39ef268b0087d66f38a9a37 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Tue, 15 Sep 2026 10:33:14 +0200 Subject: [PATCH 15/15] Properly implement the gpu-kernel ABI for amdgpu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to pass structs, arrays and vectors to amdgpu kernels. Scalars and vectors are taken by value, aggregates are passed by byref pointers. Structs containing a single scalar/vector are handled like a scalar. Judging from clang tests, nvptx seems to do somewhat the same, just using byval instead of byref: https://github.com/llvm/llvm-project/blob/3a8affeef4da19d39191aac316e189eca3214a8c/clang/test/CodeGenCUDA/kernel-args.cu I tested a couple of the lit test signatures on real hardware and it seems to work fine. Given the relatively simple implementation, I hope this amount of testing is enough (the C calling convention seems like a worse fit for Rust’s current ABI code, it’s still giving me headaches). --- compiler/rustc_abi/src/lib.rs | 4 + compiler/rustc_target/src/callconv/amdgpu.rs | 82 ++++++++++++++---- tests/codegen-llvm/amdgpu-abi/struct-abi.rs | 88 ++++++++++++++++---- 3 files changed, 139 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 9c11405e9bb58..56cfbf138af00 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1778,6 +1778,10 @@ pub struct AddressSpace(pub u32); impl AddressSpace { /// LLVM's `0` address space. pub const ZERO: Self = AddressSpace(0); + /// The address space for constant memory on nvptx and amdgpu. + /// This address space is used e.g. for kernel arguments that are constant throughout the + /// execution. + pub const GPU_CONSTANT: Self = AddressSpace(4); /// The address space for workgroup memory on nvptx and amdgpu. /// See e.g. the `gpu_launch_sized_workgroup_mem` intrinsic for details. pub const GPU_WORKGROUP: Self = AddressSpace(3); diff --git a/compiler/rustc_target/src/callconv/amdgpu.rs b/compiler/rustc_target/src/callconv/amdgpu.rs index 98ab3ce8eb746..7a9eeaba19c96 100644 --- a/compiler/rustc_target/src/callconv/amdgpu.rs +++ b/compiler/rustc_target/src/callconv/amdgpu.rs @@ -1,25 +1,60 @@ -use rustc_abi::{HasDataLayout, TyAbiInterface}; +use rustc_abi::{ + AddressSpace, BackendRepr, CanonAbi, HasDataLayout, Reg, RegKind, TyAbiInterface, TyAndLayout, +}; -use crate::callconv::{ArgAbi, FnAbi}; +use crate::callconv::{FnAbi, Uniform}; -fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>) -where - Ty: TyAbiInterface<'a, C> + Copy, - C: HasDataLayout, -{ - ret.extend_integer_width_to(32); -} +// For reference, see llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +/// If the given type is a (potentially nested) struct containing a single scalar, return +/// a `Uniform` for the contained, single element. +fn single_element_struct_to_reg<'a, Ty, C>(cx: &C, ty: TyAndLayout<'a, Ty>) -> Option where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { - if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { - arg.make_indirect(); - return; + assert!(ty.is_aggregate(), "Only handles aggregate types"); + if ty.layout.fields.count() != 1 { + return None; + } + let field = ty.field(cx, 0); + match field.backend_repr { + BackendRepr::SimdScalableVector { .. } => panic!("scalable vectors are unsupported"), + BackendRepr::Scalar(_) => { + // Check that the size is the same as the size for ty, so no extra padding + let size = field.layout.size.bytes(); + if ty.layout.size.bytes() != size { + return None; + } + + // clang passes the inner type directly, we emulate it with fitting integer types + match size { + 1 => Some(Uniform::new(Reg::i8(), field.layout.size)), + 2 => Some(Uniform::new(Reg::i16(), field.layout.size)), + 4 => Some(Uniform::new(Reg::i32(), field.layout.size)), + 8 => Some(Uniform::new(Reg::i64(), field.layout.size)), + 16 => Some(Uniform::new(Reg::i128(), field.layout.size)), + s => panic!("Unhandled scalar of size {s} in amdgpu gpu-kernel ABI"), + } + } + BackendRepr::SimdVector { element, .. } => { + // Check that the size is the same as the size for ty, so no extra padding + let size = field.layout.size.bytes(); + if ty.layout.size.bytes() != size { + return None; + } + + // clang passes the inner type directly, we emulate it with a vector of the same type. + // The size is rounded up to the size of the complete type (including alignment). + let reg = Reg { + kind: RegKind::Vector { hint_vector_elem: element.primitive() }, + size: field.layout.size, + }; + Some(Uniform::new(reg, field.layout.size)) + } + BackendRepr::Memory { .. } => single_element_struct_to_reg(cx, field), + BackendRepr::ScalarPair { .. } => None, } - arg.extend_integer_width_to(32); } pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) @@ -27,14 +62,25 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { - if !fn_abi.ret.is_ignore() { - classify_ret(cx, &mut fn_abi.ret); - } + // Kernels cannot return values, so do not handle return types + // Try to fill first registers with values and pass by_ref pointers for later indirect arguments for arg in fn_abi.args.iter_mut() { if arg.is_ignore() { continue; } - classify_arg(cx, arg); + if fn_abi.conv == CanonAbi::GpuKernel { + if arg.layout.is_aggregate() { + if let Some(uniform) = single_element_struct_to_reg(cx, arg.layout) { + // Single element structs are passed directly as the inner type + arg.cast_to(uniform); + } else { + // All other aggregates are passed as by_ref pointer in the constant address space + arg.pass_amdgpu_kernel_arg(Some(AddressSpace::GPU_CONSTANT)); + } + } + } else { + // FIXME: C ABI is not yet implemented + } } } diff --git a/tests/codegen-llvm/amdgpu-abi/struct-abi.rs b/tests/codegen-llvm/amdgpu-abi/struct-abi.rs index bf51cbfa7f7a0..bc83f6510a6fe 100644 --- a/tests/codegen-llvm/amdgpu-abi/struct-abi.rs +++ b/tests/codegen-llvm/amdgpu-abi/struct-abi.rs @@ -1,7 +1,7 @@ //@ add-minicore //@ compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 -Copt-level=3 //@ needs-llvm-components: amdgpu -#![feature(no_core, abi_gpu_kernel)] +#![feature(no_core, abi_gpu_kernel, repr_simd)] #![no_core] #![allow(improper_gpu_kernel_arg)] @@ -10,14 +10,32 @@ use minicore::num::Complex; // Tests from llvm-project/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl +#[repr(simd)] +pub struct I8X2([i8; 2]); + +#[repr(simd)] +pub struct I16X2([i16; 2]); + +#[repr(simd)] +pub struct I16X3([i16; 3]); + +#[repr(simd)] +pub struct I16X4([i16; 4]); + +#[repr(simd)] +pub struct I32X3([i32; 3]); + +#[repr(simd)] +pub struct I32X4([i32; 4]); + #[repr(C)] -pub struct SingleElementStructArg { - i: i32, +pub struct SingleElementStructArg { + i: T, } #[repr(C)] pub struct NestedSingleElementStructArg { - i: SingleElementStructArg, + i: SingleElementStructArg, } #[repr(C)] @@ -78,56 +96,92 @@ pub struct DifferentSizeTypePair { i: i32, } -// CHECK: define amdgpu_kernel void @kernel_single_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_single_element_struct_arg(i32 %0) #[no_mangle] -pub extern "gpu-kernel" fn kernel_single_element_struct_arg(_: SingleElementStructArg) {} +pub extern "gpu-kernel" fn kernel_single_element_struct_arg(_: SingleElementStructArg) {} -// CHECK: define amdgpu_kernel void @kernel_nested_single_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_nested_single_element_struct_arg(i32 %0) #[no_mangle] pub extern "gpu-kernel" fn kernel_nested_single_element_struct_arg( _: NestedSingleElementStructArg, ) { } -// CHECK: define amdgpu_kernel void @kernel_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(12) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_struct_arg(ptr addrspace(4) noalias nofree noundef readnone byref([12 x i8]) align 4 captures(none) dereferenceable(12) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_struct_arg(_: StructArg) {} -// CHECK: define amdgpu_kernel void @kernel_struct_padding_arg(i8 noundef {{%.+}}, i64 noundef {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_struct_padding_arg(ptr addrspace(4) noalias nofree noundef readnone byref([16 x i8]) align 8 captures(none) dereferenceable(16) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_struct_padding_arg(_: StructPaddingArg) {} -// CHECK: define amdgpu_kernel void @kernel_struct_of_arrays_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(44) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_struct_of_arrays_arg(ptr addrspace(4) noalias nofree noundef readnone byref([44 x i8]) align 4 captures(none) dereferenceable(44) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_struct_of_arrays_arg(_: StructOfArraysArg) {} -// CHECK: define amdgpu_kernel void @kernel_struct_of_structs_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(24) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_struct_of_structs_arg(ptr addrspace(4) noalias nofree noundef readnone byref([24 x i8]) align 4 captures(none) dereferenceable(24) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_struct_of_structs_arg(_: StructOfStructsArg) {} -// CHECK: define amdgpu_kernel void @test_kernel_union_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(4) {{%.+}}) +// CHECK: define amdgpu_kernel void @test_kernel_union_arg(ptr addrspace(4) noalias nofree noundef readnone byref([4 x i8]) align 4 captures(none) dereferenceable(4) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn test_kernel_union_arg(_: U) {} -// CHECK: define amdgpu_kernel void @kernel_single_array_element_struct_arg(ptr noalias nofree noundef readnone align 4 captures(none) dead_on_return dereferenceable(16) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_single_array_element_struct_arg(ptr addrspace(4) noalias nofree noundef readnone byref([16 x i8]) align 4 captures(none) dereferenceable(16) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_single_array_element_struct_arg(_: SingleArrayElementStructArg) {} -// CHECK: define amdgpu_kernel void @kernel_single_struct_element_struct_arg(i32 noundef {{%.+}}, i64 noundef {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_single_struct_element_struct_arg(ptr addrspace(4) noalias nofree noundef readnone byref([16 x i8]) align 8 captures(none) dereferenceable(16) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_single_struct_element_struct_arg( _: SingleStructElementStructArg, ) { } -// CHECK: define amdgpu_kernel void @kernel_different_size_type_pair_arg(i64 noundef {{%.+}}, i32 noundef {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_different_size_type_pair_arg(ptr addrspace(4) noalias nofree noundef readnone byref([16 x i8]) align 8 captures(none) dereferenceable(16) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_different_size_type_pair_arg(_: DifferentSizeTypePair) {} -// CHECK: define amdgpu_kernel void @kernel_complex(float noundef {{%.+}}, float noundef {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_complex(ptr addrspace(4) noalias nofree noundef readnone byref([8 x i8]) align 4 captures(none) dereferenceable(8) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_complex(_: Complex) {} -// CHECK: define amdgpu_kernel void @kernel_slice(ptr noalias nofree noundef nonnull readonly align 4 captures(none) {{%.+}}, i64 noundef range(i64 0, 2305843009213693952) {{%.+}}) +// CHECK: define amdgpu_kernel void @kernel_slice(ptr addrspace(4) noalias nofree noundef readnone byref([16 x i8]) align 8 captures(none) dereferenceable(16) {{%.+}}) #[no_mangle] pub extern "gpu-kernel" fn kernel_slice(_: &[u32]) {} + +// CHECK: define amdgpu_kernel void @kernel_i64(i64 noundef {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i64(_: i64) {} + +// CHECK: define amdgpu_kernel void @kernel_i64_struct(i64 {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i64_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i128_struct(i128 {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i128_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i8x2_struct(<2 x i8> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i8x2_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i16x2_struct(<2 x i16> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i16x2_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i16x3_struct(<4 x i16> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i16x3_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i16x4_struct(<4 x i16> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i16x4_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i32x3_struct(<4 x i32> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i32x3_struct(_: SingleElementStructArg) {} + +// CHECK: define amdgpu_kernel void @kernel_i32x4_struct(<4 x i32> {{%.+}}) +#[no_mangle] +pub extern "gpu-kernel" fn kernel_i32x4_struct(_: SingleElementStructArg) {}