diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index bab73fabc0767..2a103ff70eb6c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -24,7 +24,6 @@ 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_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 268153c1cbb31..620bf538a4c6a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -69,7 +69,15 @@ fn default_struct_substructure( variant_data: &VariantData, type_ident: Ident, ) -> BlockOrExpr { + // FIXME: This is currently needed to avoid a regression with attribute macros after + // derives that incorrectly rely on the generated code using `Unit {}` instead of `Unit`. + // See https://github.com/rust-lang/rust/issues/164078. + if variant_data.fields().is_empty() { + return BlockOrExpr::new_expr(cx.expr_struct_ident(trait_span, type_ident, ThinVec::new())); + } + let expr = match variant_data { + // This is currently unreachable due to the above hack. VariantData::Unit(_) => cx.expr_ident(trait_span, type_ident), VariantData::Tuple(fields, _) => { let exprs = fields diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 6828c6cd0ab4f..b9de3ce55c92b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -12,7 +12,6 @@ use rustc_errors::DiagCtxtHandle; 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 2eb4725fc5b20..18a0632a0939d 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -3,7 +3,6 @@ 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 f04c32a70390a..270ea4e88a999 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -3,7 +3,6 @@ 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 efc89075cdeb2..48fb0f6c7d4a8 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -3,7 +3,6 @@ //! [`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 959ad826359f9..5b782d5776129 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -15,7 +15,6 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods, LayoutTy #[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, HasTypingEnv as _, LayoutOf}; use rustc_middle::ty::{self, Ty}; use rustc_span::{ErrorGuaranteed, Span, Symbol, span_bug, sym}; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index be980e9938949..b7e400567b1f3 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -2,7 +2,7 @@ use std::ffi::{CStr, CString}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::sync::Arc; -use std::{fs, slice, str}; +use std::{fs, ptr, slice, str}; use libc::{c_char, c_int, c_void, size_t}; use rustc_codegen_ssa::back::link::ensure_removed; @@ -319,10 +319,22 @@ pub(crate) enum CodegenDiagnosticsStage { Codegen, } +/// Context data that is passed to [`diagnostic_handler_callback`]. +#[derive(Clone, Copy)] +struct DiagnosticHandlerCallbackData<'a> { + cgcx: &'a CodegenContext, + shared_emitter: &'a SharedEmitter, +} + pub(crate) struct DiagnosticHandlers<'a> { - data: *mut (&'a CodegenContext, &'a SharedEmitter), llcx: &'a llvm::Context, - old_handler: Option<&'a llvm::DiagnosticHandler>, + old_handler: Option>, + + /// Ownership of the box-allocated data that was installed (as a pointer) + /// alongside [`diagnostic_handler_callback`]. + /// + /// To be freed via [`Box::from_raw`] after the handler is removed. + diagnostic_handler_callback_data: *mut DiagnosticHandlerCallbackData<'a>, } impl<'a> DiagnosticHandlers<'a> { @@ -363,13 +375,14 @@ impl<'a> DiagnosticHandlers<'a> { .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok())); let pgo_available = cgcx.module_config.pgo_use.is_some(); - let data = Box::into_raw(Box::new((cgcx, shared_emitter))); + let diagnostic_handler_callback_data = + Box::into_raw(Box::new(DiagnosticHandlerCallbackData { cgcx, shared_emitter })); unsafe { - let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx); + let old_handler = llvm::LLVMRustContextTakeDiagnosticHandler(llcx); llvm::LLVMRustContextConfigureDiagnosticHandler( llcx, - diagnostic_handler, - data.cast(), + diagnostic_handler_callback, + diagnostic_handler_callback_data.cast::(), remark_passes_all, remark_passes.as_ptr(), remark_passes.len(), @@ -378,7 +391,7 @@ impl<'a> DiagnosticHandlers<'a> { remark_file.as_ref().map(|dir| dir.as_ptr()).unwrap_or(std::ptr::null()), pgo_available, ); - DiagnosticHandlers { data, llcx, old_handler } + DiagnosticHandlers { llcx, old_handler, diagnostic_handler_callback_data } } } } @@ -387,7 +400,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> { fn drop(&mut self) { unsafe { llvm::LLVMRustContextSetDiagnosticHandler(self.llcx, self.old_handler); - drop(Box::from_raw(self.data)); + drop(Box::from_raw(self.diagnostic_handler_callback_data)); } } } @@ -418,11 +431,21 @@ fn report_inline_asm( InlineAsmError { lo, hi, msg, level, source } } -unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) { - if user.is_null() { +unsafe extern "C" fn diagnostic_handler_callback(info: &DiagnosticInfo, data: *mut c_void) { + if data.is_null() { return; } - let (cgcx, shared_emitter) = unsafe { *(user as *const (&CodegenContext, &SharedEmitter)) }; + // After casting the data pointer, pass it into an inner function to limit its lifetimes. + diagnostic_handler_callback_inner(info, unsafe { + &*data.cast::>() + }); +} + +fn diagnostic_handler_callback_inner( + info: &DiagnosticInfo, + data: &DiagnosticHandlerCallbackData<'_>, +) { + let &DiagnosticHandlerCallbackData { cgcx, shared_emitter } = data; let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index e14cdeb1505d0..60a29e5c73b16 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -10,7 +10,6 @@ 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 bea61bd79f561..04368201b4576 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -19,7 +19,6 @@ use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; 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}; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 30ecd09adf8fb..1a1af50c2c025 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -731,10 +731,12 @@ pub(crate) struct OperandBundle<'a>(InvariantOpaque<'a>); pub(crate) struct Linker<'a>(InvariantOpaque<'a>); unsafe extern "C" { + /// Corresponds to LLVM's `DiagnosticHandler`. pub(crate) type DiagnosticHandler; } -pub(crate) type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); +/// Must match the declaration of `LLVMRustDiagnosticHandlerCallback`. +pub(crate) type DiagnosticHandlerCallback = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub(crate) mod debuginfo { use bitflags::bitflags; @@ -2578,17 +2580,23 @@ unsafe extern "C" { data: &ThinLTOData, ); - pub(crate) fn LLVMRustContextGetDiagnosticHandler( + /// Removes the currently-installed `DiagnosticHandler`, and returns an owning pointer to it. + pub(crate) fn LLVMRustContextTakeDiagnosticHandler( Context: &Context, - ) -> Option<&DiagnosticHandler>; + ) -> Option>; + + /// Installs a diagnostic handler that was previously removed by + /// [`LLVMRustContextTakeDiagnosticHandler`]. pub(crate) fn LLVMRustContextSetDiagnosticHandler( context: &Context, - diagnostic_handler: Option<&DiagnosticHandler>, + diagnostic_handler: Option>, ); + + /// Installs a custom diagnostic handler. pub(crate) fn LLVMRustContextConfigureDiagnosticHandler( context: &Context, - diagnostic_handler_callback: DiagnosticHandlerTy, - diagnostic_handler_context: *mut c_void, + diagnostic_handler_callback: DiagnosticHandlerCallback, + diagnostic_handler_callback_data: *mut c_void, remark_all_passes: bool, remark_passes: *const *const c_char, remark_passes_len: usize, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index e7bdb30c370dc..14e07a9c89395 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -27,7 +27,6 @@ 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 9cf68c6e3909c..810253956b186 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -20,7 +20,6 @@ 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 b6f16f72b021e..625e1dd8491db 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,7 +1,6 @@ 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 650b21bf78a9c..ade4f8a4ee8d6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,6 +1,5 @@ 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 e887572ccc197..ad8c02551570c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -8,7 +8,6 @@ use rustc_abi::{ use rustc_attr_ir::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 6391fcd58f4bb..622d205d68268 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -5,7 +5,6 @@ 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 49eb1c6d4b52e..876759b9ab41e 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -13,7 +13,6 @@ use rustc_lint_defs::builtin::LONG_RUNNING_CONST_EVAL; 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_middle::{mir, throw_machine_stop}; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 1a08c166770cf..58b8418707eff 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -2,7 +2,6 @@ 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 6cb327f1efca6..de8dd989c6a00 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -3,7 +3,6 @@ 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 1f16aab095843..79a3887d5123d 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -6,7 +6,6 @@ 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 6eee95eb2750d..30fbbcca8f6da 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/atomic.rs @@ -1,5 +1,4 @@ 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 ad191e9b4d763..476ba405f19ca 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -3,7 +3,6 @@ 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 76fd59577f248..0a7686a2876bb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -20,7 +20,6 @@ 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 86e66f7658d65..9cf88e3953d5d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -4,7 +4,6 @@ use rustc_attr_ir::lang_items::LangItem; use rustc_errors::DiagMessage; use rustc_hir as hir; 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 fead63a59b636..433392ce697a1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -42,7 +42,6 @@ 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 b1b8ecb7d1844..3e05f5019eccb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -28,7 +28,6 @@ use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin} use rustc_infer::traits::WellFormedLoc; 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 3a2cd9095a6cd..397fb560e86f4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -18,7 +18,6 @@ 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 597107f94162d..3ee9b137e5ade 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -6,7 +6,6 @@ use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level}; use rustc_hir as hir; 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 16c51ca625dcd..1c9cff2cc0607 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -21,7 +21,6 @@ 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 2c8c6a3ce7f17..2b1e0a24294d2 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -33,7 +33,6 @@ 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 9897e9cbb4f07..87b79f12838ae 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -7,7 +7,6 @@ use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; use rustc_hir::{Expr, ExprKind, HirId}; 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 89e3981b965f2..649a174233eb0 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -8,7 +8,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; 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_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 62aa8c5c57aae..f379799ecde9e 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1495,7 +1495,7 @@ extern "C" uint64_t LLVMRustModuleInstructionStats(LLVMModuleRef M) { // Transfers ownership of DiagnosticHandler unique_ptr to the caller. extern "C" DiagnosticHandler * -LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) { +LLVMRustContextTakeDiagnosticHandler(LLVMContextRef C) { std::unique_ptr DH = unwrap(C)->getDiagnosticHandler(); return DH.release(); } @@ -1507,7 +1507,9 @@ extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C, unwrap(C)->setDiagnosticHandler(std::unique_ptr(DH)); } -using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy; +// Must match `rustc_codegen_llvm::llvm::ffi::DiagnosticHandlerCallback`. +typedef void (*LLVMRustDiagnosticHandlerCallback)(LLVMDiagnosticInfoRef, + void *); // Configures a diagnostic handler that invokes provided callback when a // backend needs to emit a diagnostic. @@ -1519,22 +1521,23 @@ using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy; // If RemarkFilePath is not NULL, optimization remarks will be streamed directly // into this file, bypassing the diagnostics handler. extern "C" void LLVMRustContextConfigureDiagnosticHandler( - LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, - void *DiagnosticHandlerContext, bool RemarkAllPasses, + LLVMContextRef C, + LLVMRustDiagnosticHandlerCallback DiagnosticHandlerCallback, + void *DiagnosticHandlerCallbackData, bool RemarkAllPasses, const char *const *RemarkPasses, size_t RemarkPassesLen, const char *RemarkFilePath, bool PGOAvailable) { class RustDiagnosticHandler final : public DiagnosticHandler { public: RustDiagnosticHandler( - LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, - void *DiagnosticHandlerContext, bool RemarkAllPasses, + LLVMRustDiagnosticHandlerCallback DiagnosticHandlerCallback, + void *DiagnosticHandlerCallbackData, bool RemarkAllPasses, std::vector RemarkPasses, std::unique_ptr RemarksFile, std::unique_ptr RemarkStreamer, std::unique_ptr LlvmRemarkStreamer) : DiagnosticHandlerCallback(DiagnosticHandlerCallback), - DiagnosticHandlerContext(DiagnosticHandlerContext), + DiagnosticHandlerCallbackData(DiagnosticHandlerCallbackData), RemarkAllPasses(RemarkAllPasses), RemarkPasses(std::move(RemarkPasses)), RemarksFile(std::move(RemarksFile)), @@ -1566,7 +1569,7 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( } } if (DiagnosticHandlerCallback) { - DiagnosticHandlerCallback(&DI, DiagnosticHandlerContext); + DiagnosticHandlerCallback(wrap(&DI), DiagnosticHandlerCallbackData); return true; } return false; @@ -1600,8 +1603,8 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( return false; } - LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr; - void *DiagnosticHandlerContext = nullptr; + LLVMRustDiagnosticHandlerCallback DiagnosticHandlerCallback = nullptr; + void *DiagnosticHandlerCallbackData = nullptr; bool RemarkAllPasses = false; std::vector RemarkPasses; @@ -1654,7 +1657,7 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( } unwrap(C)->setDiagnosticHandler(std::make_unique( - DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, + DiagnosticHandlerCallback, DiagnosticHandlerCallbackData, RemarkAllPasses, Passes, std::move(RemarkFile), std::move(RemarkStreamer), std::move(LlvmRemarkStreamer))); } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 0acfe437493c0..83f62ee65025c 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -10,7 +10,6 @@ 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 daf47f991f488..c93fb42bfe7eb 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -18,7 +18,6 @@ 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 b6542fb328aac..22366f70fbe4e 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -10,7 +10,6 @@ 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.rs b/compiler/rustc_middle/src/ty/consts.rs index cbe7b6d732c0f..543185020adfc 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,11 +1,5 @@ -use rustc_macros::extension; -use rustc_span::bug; -use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir}; -use crate::mir::interpret::Scalar; -use crate::ty::{self, Ty, TyCtxt}; - mod int; mod kind; mod lit; @@ -16,6 +10,8 @@ pub use kind::*; pub use lit::*; pub use valtree::*; +use crate::ty::TyCtxt; + pub type ConstKind<'tcx> = ir::ConstKind>; pub type AliasConst<'tcx> = ir::AliasConst>; pub type AliasConstKind<'tcx> = ir::AliasConstKind>; @@ -23,126 +19,3 @@ pub type Const<'tcx> = ir::Const>; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); - -#[extension(pub trait ConstExt<'tcx>)] -impl<'tcx> Const<'tcx> { - /// Creates a constant with the given integer value and interns it. - #[inline] - fn from_bits( - tcx: TyCtxt<'tcx>, - bits: u128, - typing_env: ty::TypingEnv<'tcx>, - ty: Ty<'tcx>, - ) -> Self { - let size = tcx - .layout_of(typing_env.as_query_input(ty)) - .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) - .size; - 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. - 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. - 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. - 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`. - fn to_value(self) -> ty::Value<'tcx> { - match self.kind() { - ty::ConstKind::Value(cv) => cv, - _ => bug!("expected ConstKind::Value, got {:?}", self.kind()), - } - } - - /// Attempts to convert to a value. - /// - /// Note that this does not normalize the constant. - fn try_to_value(self) -> Option> { - match self.kind() { - ty::ConstKind::Value(cv) => Some(cv), - _ => None, - } - } - - /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing - /// if this constant is some other kind. - /// - /// Note that this does not normalize the constant. - #[inline] - fn to_leaf(self) -> ScalarInt { - self.to_value().to_leaf() - } - - /// Converts to a `ValTreeKind::Branch` value, `panic`'ing - /// if this constant is some other kind. - /// - /// Note that this does not normalize the constant. - #[inline] - 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. - 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. - 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. - fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> { - self.try_to_value()?.try_to_branch() - } - - /// Convenience method to extract the value of a usize constant, - /// useful to get the length of an array type. - /// - /// Note that this does not evaluate the constant. - #[inline] - fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_value()?.try_to_target_usize(tcx) - } - - /// 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 - /// structs or variants. For example: - /// - /// ```text - /// isize => { isize } - /// Foo> => { Foo>, Bar, isize } - /// [isize] => { [isize], isize } - /// ``` - fn walk(self) -> TypeWalker> { - TypeWalker::new(self.into()) - } -} diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 8c56cc4aafbe1..c84e9937c549c 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -8,6 +8,7 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::bug; +use crate::mir::interpret::Scalar; use crate::ty::TyCtxt; #[derive(Copy, Clone)] @@ -185,6 +186,16 @@ impl Decodable for ScalarInt { } } +impl<'tcx> rustc_type_ir::inherent::ScalarInt> for ScalarInt { + fn try_from_uint(i: impl Into, size: Size) -> Option { + Self::try_from_uint(i, size) + } + + fn to_scalar(self) -> Scalar { + Scalar::Int(self) + } +} + impl ScalarInt { pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: NonZero::new(1).unwrap() }; pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: NonZero::new(1).unwrap() }; diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 28e32a4a82d0d..2ccb05094a71b 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -11,7 +11,6 @@ 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}; @@ -228,6 +227,10 @@ impl<'tcx> Value<'tcx> { } impl<'tcx> rustc_type_ir::inherent::ValueConst> for Value<'tcx> { + fn new(ty: Ty<'tcx>, valtree: ValTree<'tcx>) -> Self { + Self { ty, valtree } + } + fn ty(self) -> Ty<'tcx> { self.ty } @@ -235,6 +238,10 @@ impl<'tcx> rustc_type_ir::inherent::ValueConst> for Value<'tcx> { fn valtree(self) -> ValTree<'tcx> { self.valtree } + + fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_target_usize(tcx) + } } impl<'tcx> fmt::Display for Value<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 5127882d0b2b8..e849f3076a9f3 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -18,6 +18,7 @@ use rustc_type_ir::{ use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::infer::canonical::CanonicalVarKinds; +use crate::mir::interpret::Scalar; use crate::traits::cache::WithDepNode; use crate::traits::solve::{ self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect, @@ -66,6 +67,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; type BoundVarKinds = &'tcx List>; + type TypingEnv = ty::TypingEnv<'tcx>; type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; @@ -116,6 +118,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ExprConst = ty::Expr<'tcx>; type ValTree = ty::ValTree<'tcx>; type ScalarInt = ty::ScalarInt; + type Scalar = Scalar; type InternedRegionKind = Interned<'tcx, ty::RegionKind<'tcx>>; type InternedConstKind = Interned<'tcx, WithCachedTypeInfo>>; type EarlyParamRegion = ty::EarlyParamRegion; @@ -716,6 +719,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> { )) } } + + fn intern_valtree(self, valtree_kind: ty::ValTreeKind>) -> ty::ValTree<'tcx> { + self.intern_valtree(valtree_kind) + } + + fn const_zst(self) -> ty::ValTree<'tcx> { + self.consts.valtree_zst + } } impl<'tcx, T: Clone + Copy> rustc_type_ir::intern::Interned> for Interned<'tcx, T> { diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 61e3a40e363d9..6b0234c971830 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -4,7 +4,6 @@ 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 03c5c21de02c9..5e36b1f1b6b26 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -50,7 +50,6 @@ 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 4ee2e5c7e3fdd..998fcf77f7b1f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -21,7 +21,6 @@ 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}; @@ -1428,6 +1427,7 @@ pub fn codegen_handle_fn_abi_err<'tcx>( fn_abi_request: FnAbiRequest<'tcx>, ) -> ErrorGuaranteed { match err { + FnAbiError::Layout(LayoutError::ReferencesError(guar)) => guar, FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) => { tcx.dcx().emit_err(Spanned { span, node: err }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1f2ffb17cc2c7..149c5f6e91592 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -26,7 +26,7 @@ pub use generic_args::{GenericArgKind, TermKind, *}; pub use generics::*; pub use intrinsic::IntrinsicDef; use rustc_abi::{ - Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, VariantIdx, + Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, Size, VariantIdx, }; use rustc_ast::{self as ast}; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; @@ -1109,6 +1109,18 @@ pub struct TypingEnv<'tcx> { pub param_env: ParamEnv<'tcx>, } +impl<'tcx> rustc_type_ir::inherent::TypingEnv> for TypingEnv<'tcx> { + fn fully_monomorphized() -> Self { + Self::fully_monomorphized() + } + + fn layout_size(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Size { + tcx.layout_of(self.as_query_input(ty)) + .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) + .size + } +} + impl<'tcx> TypingEnv<'tcx> { pub fn new(param_env: ParamEnv<'tcx>, typing_mode: TypingMode<'tcx>) -> Self { Self { typing_mode: TypingModeEqWrapper(typing_mode), param_env } diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 71d3bf0853f04..2d73124265fc2 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -7,7 +7,6 @@ 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/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index cafe93c591090..61ba4a70b5f17 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -24,7 +24,6 @@ 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, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 4673ff428934b..09a18c858db17 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -27,7 +27,6 @@ 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 54cbc591c5fb3..c2479e0c62bca 100644 --- a/compiler/rustc_middle/src/ty/typetree.rs +++ b/compiler/rustc_middle/src/ty/typetree.rs @@ -2,7 +2,6 @@ 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 0974e0a332ecd..83589adb1691b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -26,7 +26,6 @@ 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 18dea6dafd2dd..80e6ed2036798 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -8,7 +8,6 @@ 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 57ffee758b325..392712619a3f2 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -3,7 +3,6 @@ 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 1e65ddf3372a9..64a1fea013ace 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -17,7 +17,6 @@ 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 79505dd6f03fc..1f3b6f35c17be 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -91,7 +91,6 @@ 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 a669e09475232..6a78135f22dcf 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,7 +1,6 @@ use rustc_abi::Size; use rustc_ast::{self as ast, UintTy}; use rustc_attr_ir::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 53c723bb02a0d..f9a91878a47c2 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,7 +12,6 @@ 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 f5e44d768faa1..5b7a4d626aae3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -19,7 +19,6 @@ 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 26628a05188d7..90fb709eb8ad6 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -2,7 +2,6 @@ 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 ab500d12b8aa3..8742529d7015b 100644 --- a/compiler/rustc_mir_transform/src/coroutine/layout.rs +++ b/compiler/rustc_mir_transform/src/coroutine/layout.rs @@ -34,7 +34,6 @@ 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 db8d5d6fd23b9..53739284f8c0f 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -7,7 +7,6 @@ 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 e1b1f6f9ff68c..4d543ff27e502 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -114,7 +114,6 @@ 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 eaedb7c9aca3d..f1a31db86c6dc 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -6,7 +6,6 @@ use rustc_attr_ir::lang_items::LangItem; 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 e25ed11d7a265..f448371977068 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -16,7 +16,6 @@ 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 b490ebb3a9392..463cca7214edb 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -22,7 +22,6 @@ 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 98f4009c15665..09379fc252072 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -2,7 +2,6 @@ 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 581f1061bb80c..5e6b682626210 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -9,7 +9,6 @@ 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 742e863749518..c74dc713ba368 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -11,7 +11,6 @@ use rustc_crate_store::ForeignModule; 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, HasTypingEnv, 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 2ed970bf71166..e0f68b37b0a7f 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,7 +12,6 @@ use rustc_attr_ir::find_attr; use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; -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_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index e5b4628374ce5..ba89f40b60254 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{ use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, bug}; use rustc_trait_selection::traits; -use tracing::{debug, instrument}; +use tracing::instrument; use crate::cfi::typeid::TypeIdOptions; use crate::cfi::typeid::itanium_cxx_abi::encode::EncodeTyOptions; @@ -75,7 +75,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { ty::Bool => { if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { - // Note: on all platforms that Rust's currently supports, its size and alignment + // Note: on all platforms that Rust currently supports, its size and alignment // are 1, and its ABI class is INTEGER - see Rust Layout and ABIs. // // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#bool.) @@ -100,8 +100,10 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { ty::Int(..) | ty::Uint(..) => { if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { // Note: C99 7.18.2.4 requires uintptr_t and intptr_t to be at least 16-bit - // wide. All platforms we currently support have a C platform, and as a - // consequence, isize/usize are at least 16-bit wide for all of them. + // wide. All platforms that Rust currently supports have a C platform, and as + // a consequence, isize/usize are at least 16-bit wide for all of them. This is + // also guaranteed by the stable `From for isize` and `From for usize` + // implementations. // // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize.) match t.kind() { @@ -162,7 +164,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { // contains or references itself, to avoid a reference cycle. // If the self reference is not through a pointer, for example, due - // to using `PhantomData`, need to skip normalizing it if we hit it again. + // to using `PhantomData`, need to skip normalizing it if it is hit again. self.parents.push(t); let ty = if ty0.is_any_ptr() && ty0.contains(t) { let options = self.options; @@ -176,7 +178,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { self.parents.pop(); ty } else { - // Transform repr(transparent) types without non-ZST field into () + // Transform repr(transparent) types without non-ZST field into (). self.tcx.types.unit } } else { @@ -232,13 +234,25 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } } +/// Returns whether a trait method may be called through a vtable. +fn may_be_called_through_vtable(tcx: TyCtxt<'_>, method_id: DefId) -> bool { + let trait_id = tcx.parent(method_id); + traits::is_vtable_safe_method(tcx, trait_id, tcx.associated_item(method_id)) + && tcx.is_dyn_compatible(trait_id) +} + +/// Returns the trait object type of a trait reference (i.e., a dyn Trait type with the trait as +/// its principal trait, and the associated types of the trait and its supertraits as its +/// projections), for self to be transformed into when performing type erasure. #[instrument(skip(tcx), ret)] fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> { - assert!(!poly_trait_ref.has_non_region_param()); - let principal_pred = poly_trait_ref.map_bound(|trait_ref| { + if poly_trait_ref.has_non_region_param() { + bug!("trait_object_ty: unexpected non-region param in `{:?}`", poly_trait_ref); + } + let principal_predicate = poly_trait_ref.map_bound(|trait_ref| { ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)) }); - let mut assoc_preds: Vec<_> = traits::supertraits(tcx, poly_trait_ref) + let mut assoc_predicates: Vec<_> = traits::supertraits(tcx, poly_trait_ref) .flat_map(|super_poly_trait_ref| { tcx.associated_items(super_poly_trait_ref.def_id()) .in_definition_order() @@ -253,27 +267,206 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc }; let projection_term = ty::AliasTerm::new_from_args(tcx, kind, super_trait_ref.args); - let term = projection_term.to_term(tcx, ty::IsRigid::No); - let normalized_term = tcx.normalize_erasing_regions( + let term = tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - Unnormalized::new_wip(term), + Unnormalized::new_wip(projection_term.to_term(tcx, ty::IsRigid::No)), ); - debug!("Projection {term} -> {normalized_term}"); ty::ExistentialPredicate::Projection( ty::ExistentialProjection::erase_self_ty( tcx, - ty::ProjectionClause { projection_term, term: normalized_term }, + ty::ProjectionClause { projection_term, term }, ), ) }) }) }) .collect(); - assoc_preds.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); - let preds = tcx.mk_poly_existential_predicates_from_iter( - iter::once(principal_pred).chain(assoc_preds.into_iter()), + assoc_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); + let predicates = tcx.mk_poly_existential_predicates_from_iter( + iter::once(principal_predicate).chain(assoc_predicates), + ); + Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased) +} + +/// Performs type erasure for closure-likes (i.e., instances identified by the def id of a +/// closure, coroutine, or coroutine-closure) by transforming self into a trait object of the Fn, +/// FnMut, FnOnce, Coroutine, Future, Iterator, or AsyncIterator trait that defines the call +/// method they are called through, and the instance into a virtual call to that method, to match +/// the type erasure performed during code generation at call sites (see transform_virtual_call). +/// Returns None if the instance is not a closure-like. +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// // The closure is transformed into ::call. +/// let f: Box = Box::new(|_x| {}); +/// f(0); +/// ``` +fn transform_closure_like<'tcx>( + tcx: TyCtxt<'tcx>, + mut instance: Instance<'tcx>, +) -> Option> { + if !tcx.is_closure_like(instance.def_id()) { + return None; + } + let closure_like_ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let (trait_id, call_method_id, inputs) = match closure_like_ty.kind() { + ty::Closure(_, args) => { + let closure_args = args.as_closure(); + let closure_kind = closure_args.kind(); + let trait_id = tcx.fn_trait_kind_to_def_id(closure_kind).unwrap_or_else(|| { + bug!( + "transform_closure_like: couldn't get trait of closure kind `{:?}`", + closure_kind + ) + }); + let tuple_args = + tcx.instantiate_bound_regions_with_erased(closure_args.sig()).inputs()[0]; + (trait_id, None, Some(tuple_args)) + } + ty::Coroutine(_, args) => match tcx.coroutine_kind(instance.def_id()).unwrap_or_else(|| { + bug!("transform_closure_like: couldn't get coroutine kind of `{:?}`", instance.def_id()) + }) { + hir::CoroutineKind::Coroutine(..) => ( + tcx.require_lang_item(LangItem::Coroutine, DUMMY_SP), + Some(tcx.require_lang_item(LangItem::CoroutineResume, DUMMY_SP)), + Some(args.as_coroutine().resume_ty()), + ), + hir::CoroutineKind::Desugared(desugaring, _) => { + let (trait_lang_item, call_method_lang_item) = match desugaring { + hir::CoroutineDesugaring::Async => (LangItem::Future, LangItem::FuturePoll), + hir::CoroutineDesugaring::AsyncGen => { + (LangItem::AsyncIterator, LangItem::AsyncIteratorPollNext) + } + hir::CoroutineDesugaring::Gen => (LangItem::Iterator, LangItem::IteratorNext), + }; + ( + tcx.require_lang_item(trait_lang_item, DUMMY_SP), + Some(tcx.require_lang_item(call_method_lang_item, DUMMY_SP)), + None, + ) + } + }, + ty::CoroutineClosure(_, args) => ( + tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP), + None, + Some( + tcx.instantiate_bound_regions_with_erased( + args.as_coroutine_closure().coroutine_closure_sig(), + ) + .tupled_inputs_ty, + ), + ), + _ => bug!("transform_closure_like: unexpected `{:?}`", closure_like_ty.kind()), + }; + let call_method_id = call_method_id.unwrap_or_else(|| { + // The Fn, FnMut, and FnOnce traits do not have lang items for their call methods, and each + // has a single method, which is the one being defined. + tcx.associated_items(trait_id) + .in_definition_order() + .find(|item| item.is_fn()) + .unwrap_or_else(|| { + bug!("transform_closure_like: couldn't get call method of `{:?}`", trait_id) + }) + .def_id + }); + let concrete_args = tcx.mk_args_trait(closure_like_ty, inputs.map(Into::into)); + let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, concrete_args); + let self_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); + let abstract_args = tcx.mk_args_trait(self_ty, trait_ref.args.into_iter().skip(1)); + + instance.def = ty::InstanceKind::Virtual(call_method_id, 0); + instance.args = abstract_args; + Some(instance) +} + +/// Adjusts the type ids of DropGlues to a synthesized Drop trait object. +/// +/// DropGlues may have indirect calls to one or more given types' drop function. Rust allows for +/// types to be erased to any trait object and retains the drop function for the original type, +/// which means at the indirect call sites in DropGlues, when typeid_for_fnabi is called a second +/// time, it only has information after type erasure and it could be a call on any arbitrary trait +/// object. They are normalized to a synthesized Drop trait object, both on declaration/definition, +/// and during code generation at call sites so they have the same type id and match. +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// struct Type1; +/// +/// impl Drop for Type1 { +/// fn drop(&mut self) {} +/// } +/// +/// let x: Box = Box::new(Type1); +/// // Dropping x calls the drop glue of Type1 through the vtable of the dyn Send trait object. +/// // Both the drop glue and the virtual drop call to it are transformed into +/// // drop_in_place::. +/// ``` +/// +/// FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of any +/// other type. +/// +fn transform_drop_glue<'tcx>(tcx: TyCtxt<'tcx>, mut instance: Instance<'tcx>) -> Instance<'tcx> { + let trait_id = tcx + .lang_items() + .drop_trait() + .unwrap_or_else(|| bug!("transform_drop_glue: couldn't get drop_trait lang item")); + let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new_from_args( + tcx, + trait_id, + ty::List::empty(), + )); + let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]); + let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased); + instance.args = tcx.mk_args_trait(self_ty, List::empty()); + instance +} + +/// Performs type erasure for trait method implementations in impl blocks by transforming self +/// into a trait object of the trait that defines the method, and the instance into a virtual call +/// to the trait method definition it implements, to match the type erasure performed during code +/// generation at call sites (see transform_virtual_call). Returns None if the instance is not a +/// trait method implementation in an impl block that may be called through a vtable. +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// trait Trait1 { +/// fn foo(&self); +/// } +/// +/// struct Type1; +/// +/// impl Trait1 for Type1 { +/// fn foo(&self) {} // ::foo is transformed into ::foo. +/// } +/// +/// let x: &dyn Trait1 = &Type1; +/// x.foo(); +/// ``` +fn transform_impl_method<'tcx>( + tcx: TyCtxt<'tcx>, + mut instance: Instance<'tcx>, +) -> Option> { + let assoc = tcx.opt_associated_item(instance.def_id())?; + let AssocContainer::TraitImpl(Ok(method_id)) = assoc.container else { + return None; + }; + if !may_be_called_through_vtable(tcx, method_id) { + return None; + } + let impl_id = tcx.parent(instance.def_id()); + let trait_ref = tcx.instantiate_and_normalize_erasing_regions( + instance.args, + ty::TypingEnv::fully_monomorphized(), + tcx.impl_trait_ref(impl_id), ); - Ty::new_dynamic(tcx, preds, tcx.lifetimes.re_erased) + let self_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); + instance.def = ty::InstanceKind::Virtual(method_id, 0); + let abstract_args = tcx.mk_args_trait(self_ty, trait_ref.args.into_iter().skip(1)); + instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_args); + Some(instance) } /// Transforms an instance for LLVM CFI and cross-language LLVM CFI support using Itanium C++ ABI @@ -294,228 +487,305 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc /// most as much information that would be available in the second call (i.e., during code /// generation at call sites); otherwise, the type ids would not match. /// -/// For this, it: +/// For this, it covers each InstanceKind (and ShimKind) explicitly, and either: /// -/// * Adjust the type ids of DropGlues (see below). -/// * Adjusts the type ids of VTableShims to the type id expected in the call sites for the -/// entry in the vtable (i.e., by using the signature of the closure passed as an argument to the -/// shim, or by just removing self). +/// * Performs type erasure for closures and coroutines by transforming self into a trait object +/// of the Fn, FnMut, FnOnce, Coroutine, Future, Iterator, or AsyncIterator trait that defines +/// the call method they are called through (see transform_closure_like). /// * Performs type erasure for calls on trait objects by transforming self into a trait object of -/// the trait that defines the method. -/// * Performs type erasure for closures call methods by transforming self into a trait object of -/// the Fn trait that defines the method (for being attached as a secondary type id). +/// the trait that defines the method, both on declaration/definition (see +/// transform_impl_method and transform_provided_method) and during code generation at call +/// sites (see transform_virtual_call). +/// * Adjusts the type ids of VTableShims to the type id expected in the call sites for the +/// entry in the vtable by transforming self into a trait object of the trait that defines the +/// method (see transform_vtable_shim). +/// * Adjusts the type ids of DropGlues to a synthesized Drop trait object (see +/// transform_drop_glue). +/// * Does not transform the instance (i.e., encodes type ids for the instance as is). /// #[instrument(level = "trace", skip(tcx))] pub(crate) fn transform_instance<'tcx>( tcx: TyCtxt<'tcx>, - mut instance: Instance<'tcx>, + instance: Instance<'tcx>, options: TransformTyOptions, ) -> Instance<'tcx> { - // FIXME: account for async-drop-glue - if (matches!(instance.def, ty::InstanceKind::Virtual(..)) - && tcx.is_lang_item(instance.def_id(), LangItem::DropGlue)) - || matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..))) - { - // Adjust the type ids of DropGlues + // If the USE_CONCRETE_SELF option is set, type erasure is not performed for the instances + // that may also be called directly (i.e., type ids are encoded for them as is). The + // USE_CONCRETE_SELF option is set for encoding methods as concrete types for being attached + // as secondary type ids (see rustc_codegen_llvm::declare::declare_fn), and for ReifyShims + // created for function pointers (i.e., ReifyReason::FnPtr) when KCFI is enabled (see + // kcfi::typeid_for_instance). Note that DropGlues, virtual method calls, and VTableShims are + // transformed regardless of this option (see below). + let erase_self = !options.contains(TransformTyOptions::USE_CONCRETE_SELF); + match instance.def { + // User-defined callable items (i.e., fn items, closures, and coroutines): + // + // * Closures and coroutines are called through the call methods of the Fn, FnMut, FnOnce, + // Coroutine, Future, Iterator, or AsyncIterator traits they implement, either on the + // concrete type or through a vtable, so type erasure is performed for them (see + // transform_closure_like). + // * Fn items that implement a trait method may be called through a vtable, so type + // erasure is also performed for them, both for trait method implementations in impl + // blocks (see transform_impl_method) and for provided (default) trait methods in trait + // blocks (see transform_provided_method). + // * Other fn items (i.e., free functions, inherent methods, and trait methods that can + // not be called through a vtable) are not transformed (i.e., type ids are encoded for + // them as is). + ty::InstanceKind::Item(..) => { + if erase_self { + transform_closure_like(tcx, instance) + .or_else(|| transform_impl_method(tcx, instance)) + .or_else(|| transform_provided_method(tcx, instance)) + .unwrap_or(instance) + } else { + instance + } + } + + // Intrinsic fn items (i.e., fn items with #[rustc_intrinsic]) and LLVM intrinsic fn items + // (i.e., fn items with extern "llvm-intrinsic"): intrinsics lowered by codegen do not have + // their own callable MIR and can not be reified or called indirectly, so they are not + // transformed (i.e., type ids are encoded for them as is). (Note that the fallback body of + // an intrinsic uses InstanceKind::Item, handled above.) + ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::LlvmIntrinsic(..) => instance, + + // Virtual method calls (i.e., dynamic dispatch through the vtable): // - // DropGlues may have indirect calls to one or more given types drop function. Rust allows - // for types to be erased to any trait object and retains the drop function for the original - // type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is - // called a second time, it only has information after type erasure and it could be a call - // on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on - // declaration/definition, and during code generation at call sites so they have the same - // type id and match. + // * Virtual drop glue calls (i.e., the drop function entry in vtables) are normalized to + // a synthesized Drop trait object to match the DropGlues (see transform_drop_glue). + // * Other virtual method calls have self transformed into a trait object of the trait + // that defines the method to match the type erasure performed on + // declaration/definition (see transform_virtual_call). + ty::InstanceKind::Virtual(def_id, _) => { + if tcx.is_lang_item(def_id, LangItem::DropGlue) { + transform_drop_glue(tcx, instance) + } else { + transform_virtual_call(tcx, instance) + } + } + + // VTableShims (i.e., shims for trait methods that receive an unsizeable `self: Self`): + // have their type ids adjusted to the type id expected in the call sites for the entry in + // the vtable (see transform_vtable_shim). + ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) => transform_vtable_shim(tcx, instance), + + // ReifyShims (i.e., fn pointers created for methods that can not be directly reified, + // such as virtual methods and methods with #[track_caller]): // - // FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of - // any other type. + // * ReifyShims for trait method implementations (in impl blocks) may be called through a + // vtable, so type erasure is performed for them (see transform_impl_method). + // * ReifyShims for trait method definitions (e.g., fn pointers created for virtual + // calls) and for free functions are not transformed (i.e., type ids are encoded for + // them as is). // - let def_id = tcx - .lang_items() - .drop_trait() - .unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item")); - let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new_from_args( - tcx, - def_id, - ty::List::empty(), - )); - let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]); - let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased); - instance.args = tcx.mk_args_trait(self_ty, List::empty()); - } else if let ty::InstanceKind::Virtual(def_id, _) = instance.def { - // Transform self into a trait object of the trait that defines the method for virtual - // functions to match the type erasure done below. - let upcast_ty = match tcx.trait_of_assoc(def_id) { - Some(trait_id) => trait_object_ty( - tcx, - ty::Binder::dummy(ty::TraitRef::from_assoc(tcx, trait_id, instance.args)), - ), - // drop_in_place won't have a defining trait, skip the upcast - None => instance.args.type_at(0), - }; - let ty::Dynamic(preds, lifetime) = upcast_ty.kind() else { - bug!("Tried to remove autotraits from non-dynamic type {upcast_ty}"); - }; - let self_ty = if preds.principal().is_some() { - let filtered_preds = - tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| { - !matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..)) - })); - Ty::new_dynamic(tcx, filtered_preds, *lifetime) - } else { - // If there's no principal type, re-encode it as a unit, since we don't know anything - // about it. This technically discards the knowledge that it was a type that was made - // into a trait object at some point, but that's not a lot. - tcx.types.unit - }; - instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); - } else if let ty::InstanceKind::Shim(ty::ShimKind::VTable(def_id)) = instance.def - && let Some(trait_id) = tcx.trait_of_assoc(def_id) - { - // Adjust the type ids of VTableShims to the type id expected in the call sites for the - // entry in the vtable (i.e., by using the signature of the closure passed as an argument - // to the shim, or by just removing self). - let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, instance.args); - let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); - instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1)); - } + // Note: when KCFI is enabled, ReifyShims created for function pointers (i.e., + // ReifyReason::FnPtr) have the USE_CONCRETE_SELF option set (see + // kcfi::typeid_for_instance), so type erasure is not performed for them. + ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) => { + if erase_self { + transform_impl_method(tcx, instance).unwrap_or(instance) + } else { + instance + } + } - if !options.contains(TransformTyOptions::USE_CONCRETE_SELF) { - // Perform type erasure for calls on trait objects by transforming self into a trait object - // of the trait that defines the method. - if let Some((trait_ref, method_id, ancestor)) = implemented_method(tcx, instance) { - // Trait methods will have a Self polymorphic parameter, where the concreteized - // implementation will not. We need to walk back to the more general trait method - let trait_ref = tcx.instantiate_and_normalize_erasing_regions( - instance.args, - ty::TypingEnv::fully_monomorphized(), - trait_ref, - ); - let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); - - // At the call site, any call to this concrete function through a vtable will be - // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the - // original method id, and we've recovered the trait arguments, we can make the callee - // instance we're computing the alias set for match the caller instance. - // - // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder. - // If we ever *do* start encoding the vtable index, we will need to generate an alias set - // based on which vtables we are putting this method into, as there will be more than one - // index value when supertraits are involved. - instance.def = ty::InstanceKind::Virtual(method_id, 0); - let abstract_trait_args = - tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1)); - instance.args = instance.args.rebase_onto(tcx, ancestor, abstract_trait_args); - } else if tcx.is_closure_like(instance.def_id()) { - // We're either a closure or a coroutine. Our goal is to find the trait we're defined on, - // instantiate it, and take the type of its only method as our own. - let closure_ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); - let (trait_id, inputs) = match closure_ty.kind() { - ty::Closure(..) => { - let closure_args = instance.args.as_closure(); - let trait_id = tcx.fn_trait_kind_to_def_id(closure_args.kind()).unwrap(); - let tuple_args = - tcx.instantiate_bound_regions_with_erased(closure_args.sig()).inputs()[0]; - (trait_id, Some(tuple_args)) - } - ty::Coroutine(..) => match tcx.coroutine_kind(instance.def_id()).unwrap() { - hir::CoroutineKind::Coroutine(..) => ( - tcx.require_lang_item(LangItem::Coroutine, DUMMY_SP), - Some(instance.args.as_coroutine().resume_ty()), - ), - hir::CoroutineKind::Desugared(desugaring, _) => { - let lang_item = match desugaring { - hir::CoroutineDesugaring::Async => LangItem::Future, - hir::CoroutineDesugaring::AsyncGen => LangItem::AsyncIterator, - hir::CoroutineDesugaring::Gen => LangItem::Iterator, - }; - (tcx.require_lang_item(lang_item, DUMMY_SP), None) - } - }, - ty::CoroutineClosure(..) => ( - tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP), - Some( - tcx.instantiate_bound_regions_with_erased( - instance.args.as_coroutine_closure().coroutine_closure_sig(), - ) - .tupled_inputs_ty, - ), - ), - x => bug!("Unexpected type kind for closure-like: {x:?}"), - }; - let concrete_args = tcx.mk_args_trait(closure_ty, inputs.map(Into::into)); - let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, concrete_args); - let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); - let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1)); - // There should be exactly one method on this trait, and it should be the one we're - // defining. - let call = tcx - .associated_items(trait_id) - .in_definition_order() - .find(|it| it.is_fn()) - .expect("No call-family function on closure-like Fn trait?") - .def_id; + // FnPtrShims (i.e., `::call_*`, the generated Fn, FnMut, and FnOnce + // trait implementations for fn pointers): may be called through a vtable (e.g., a + // `dyn Fn` trait object created from a fn pointer or fn item), so type erasure is + // performed for them (see transform_impl_method and transform_provided_method). + ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) => { + if erase_self { + transform_impl_method(tcx, instance) + .or_else(|| transform_provided_method(tcx, instance)) + .unwrap_or(instance) + } else { + instance + } + } - instance.def = ty::InstanceKind::Virtual(call, 0); - instance.args = abstract_args; + // ClosureOnceShims (i.e., `<[FnMut/Fn closure] as FnOnce>::call_once`): + // `FnOnce::call_once` receives an unsizeable `self: Self`, so when it is called through a + // `dyn FnOnce` trait object, the entry in the vtable is a VTableShim (handled above), + // which calls the ClosureOnceShim directly. ClosureOnceShims can not be called through a + // vtable, so they are not transformed (i.e., type ids are encoded for them as is). + ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) => instance, + + // ConstructCoroutineInClosureShims (i.e., `<[FnMut/Fn coroutine-closure] as + // FnOnce>::call_once`, identified by the def id of the coroutine-closure): may be called + // through a vtable (e.g., a `dyn FnOnce` trait object created from a coroutine-closure), + // so type erasure is performed for them (see transform_closure_like). + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) => { + if erase_self { + transform_closure_like(tcx, instance).unwrap_or(instance) + } else { + instance + } } - } - instance -} + // ThreadLocalShims (i.e., compiler-generated accessors for thread locals): can not be + // reified or called indirectly, so they are not transformed (i.e., type ids are encoded + // for them as is). + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => instance, -fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { - match instance.def { - ty::InstanceKind::Item(def_id) | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(def_id, _)) => { - tcx.opt_associated_item(def_id).map(|item| item.def_id) + // FutureDropPollShims (i.e., proxy poll functions for async drop of futures) and + // AsyncDropGlueShims (i.e., poll functions of the `async_drop_in_place::::{closure}` + // coroutines): identified by the def id of the `async_drop_in_place::::{closure}` + // coroutine, so type erasure is performed for them like other coroutines (i.e., self is + // transformed into a Future trait object) (see transform_closure_like). + // + // FIXME: account for async-drop-glue: similarly to DropGlues (see transform_drop_glue), + // at the indirect call sites in async drop glue the receiver may have been erased to + // any trait object, so async drop glue may need to be normalized to a synthesized + // trait object instead. + ty::InstanceKind::Shim( + ty::ShimKind::FutureDropPoll(..) | ty::ShimKind::AsyncDropGlue(..), + ) => { + if erase_self { + transform_closure_like(tcx, instance).unwrap_or(instance) + } else { + instance + } + } + + // DropGlues (i.e., `core::ptr::drop_glue::`): normalized to a synthesized Drop trait + // object (see transform_drop_glue). + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) => transform_drop_glue(tcx, instance), + + // CloneShims (i.e., compiler-generated `::clone` implementations for types + // with builtin Clone impls, such as arrays, tuples, and closures): the Clone trait is not + // dyn compatible, so they can not be called through a vtable and are not transformed + // (i.e., type ids are encoded for them as is). + ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) => instance, + + // FnPtrAsPtrShims and FnPtrFromPtrShims (i.e., compiler-generated `::as_ptr` + // and `::from_ptr` implementations): the FnPtr trait is not dyn compatible, so + // they can not be called through a vtable and are not transformed (i.e., type ids are + // encoded for them as is). + ty::InstanceKind::Shim(ty::ShimKind::FnPtrAsPtr(..) | ty::ShimKind::FnPtrFromPtr(..)) => { + instance } - _ => None, + + // AsyncDropGlueCtorShims (i.e., `core::future::async_drop::async_drop_in_place::<'_, + // T>`, the constructors of the async drop glue coroutines): do not implement any trait + // method and are not closure-likes, so they are not transformed (i.e., type ids are + // encoded for them as is). + // + // FIXME: account for async-drop-glue (see the FutureDropPollShims and AsyncDropGlueShims + // above). + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) => instance, } } -/// Determines if an instance represents a trait method implementation and returns the necessary -/// information for type erasure. +/// Performs type erasure for provided (default) trait methods in trait blocks and synthetic +/// FnPtrShims by transforming self into a trait object of the trait that defines the method, and +/// the instance into a virtual call to the trait method definition, to match the type erasure +/// performed during code generation at call sites (see transform_virtual_call). Returns None if +/// the instance is not a provided (default) trait method or a synthetic FnPtrShim that may be +/// called through a vtable. +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// trait Trait1 { +/// fn foo(&self) {} // ::foo is transformed into ::foo. +/// } +/// +/// struct Type1; +/// +/// impl Trait1 for Type1 {} /// -/// This function handles two main cases: +/// let x: &dyn Trait1 = &Type1; +/// x.foo(); +/// ``` /// -/// * **Implementation in an `impl` block**: When the instance represents a concrete implementation -/// of a trait method in an `impl` block, it extracts the trait reference, method ID, and trait -/// ID from the implementation. The method ID is obtained from the `trait_item_def_id` field of -/// the associated item, which points to the original trait method definition. +/// And for synthetic FnPtrShims: /// -/// * **Provided method in a `trait` block or synthetic `shim`**: When the instance represents a -/// default implementation provided in the trait definition itself or a synthetic shim, it uses -/// the instance's own `def_id` as the method ID and determines the trait ID from the associated -/// item. +/// ```ignore (illustrative) +/// fn foo(_: i32) {} /// -fn implemented_method<'tcx>( +/// let f: Box = Box::new(foo); +/// f(0); +/// // The ::call FnPtrShim is transformed into +/// // ::call. +/// ``` +fn transform_provided_method<'tcx>( tcx: TyCtxt<'tcx>, - instance: Instance<'tcx>, -) -> Option<(ty::EarlyBinder<'tcx, TraitRef<'tcx>>, DefId, DefId)> { - let trait_ref; - let method_id; - let trait_id; - let trait_method; + mut instance: Instance<'tcx>, +) -> Option> { let assoc = tcx.opt_associated_item(instance.def_id())?; - let ancestor = if let AssocContainer::TraitImpl(Ok(trait_method_id)) = assoc.container { - let impl_id = tcx.parent(instance.def_id()); - trait_ref = tcx.impl_trait_ref(impl_id); - method_id = trait_method_id; - trait_method = tcx.associated_item(method_id); - trait_id = trait_ref.skip_binder().def_id; - impl_id - } else if let AssocContainer::Trait = assoc.container - && let Some(trait_method_def_id) = default_or_shim(tcx, instance) - { - // Provided method in a `trait` block or a synthetic `shim` - trait_method = assoc; - method_id = trait_method_def_id; - trait_id = tcx.parent(method_id); - trait_ref = ty::EarlyBinder::bind(tcx, TraitRef::from_assoc(tcx, trait_id, instance.args)); - trait_id - } else { + let AssocContainer::Trait = assoc.container else { return None; }; - let vtable_possible = traits::is_vtable_safe_method(tcx, trait_id, trait_method) - && tcx.is_dyn_compatible(trait_id); - vtable_possible.then_some((trait_ref, method_id, ancestor)) + let method_id = assoc.def_id; + if !may_be_called_through_vtable(tcx, method_id) { + return None; + } + let trait_id = tcx.parent(method_id); + let trait_ref = tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(TraitRef::from_assoc(tcx, trait_id, instance.args)), + ); + let self_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); + instance.def = ty::InstanceKind::Virtual(method_id, 0); + let abstract_args = tcx.mk_args_trait(self_ty, trait_ref.args.into_iter().skip(1)); + instance.args = instance.args.rebase_onto(tcx, trait_id, abstract_args); + Some(instance) +} + +/// Performs type erasure for virtual method calls (i.e., calls to methods through trait objects) +/// by transforming self into a trait object of the trait that defines the method, to match the +/// type erasure performed on declaration/definition (see transform_impl_method, +/// transform_provided_method, and transform_closure_like). +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// trait Trait1 { +/// fn foo(&self); +/// } +/// +/// struct Type1; +/// +/// impl Trait1 for Type1 { +/// fn foo(&self) {} +/// } +/// +/// let x: &dyn Trait1 = &Type1; +/// x.foo(); // The virtual method call is transformed into ::foo. +/// ``` +fn transform_virtual_call<'tcx>(tcx: TyCtxt<'tcx>, mut instance: Instance<'tcx>) -> Instance<'tcx> { + // Virtual method calls are either drop glue calls (handled above) or calls to trait methods, + // so they always have a defining trait. + let trait_id = tcx.trait_of_assoc(instance.def_id()).unwrap_or_else(|| { + bug!("transform_virtual_call: couldn't get defining trait of `{:?}`", instance.def_id()) + }); + let trait_ref = ty::TraitRef::from_assoc(tcx, trait_id, instance.args); + let self_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); + instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); + instance +} + +/// Adjusts the type ids of VTableShims to the type id expected in the call sites for the entry in +/// the vtable by transforming self into a trait object of the trait that defines the method, to +/// match the type erasure performed during code generation at call sites (see +/// transform_virtual_call). +/// +/// E.g.: +/// +/// ```ignore (illustrative) +/// let f: Box = Box::new(|| {}); +/// f(); +/// // ::call_once receives an unsizeable `self: Self`, so the +/// // VTableShim for it in the vtable is transformed into ::call_once. +/// ``` +fn transform_vtable_shim<'tcx>(tcx: TyCtxt<'tcx>, mut instance: Instance<'tcx>) -> Instance<'tcx> { + // VTableShims are only created for trait methods (see Instance::expect_resolve_for_vtable), + // so they always have a defining trait. + let trait_id = tcx.trait_of_assoc(instance.def_id()).unwrap_or_else(|| { + bug!("transform_vtable_shim: couldn't get defining trait of `{:?}`", instance.def_id()) + }); + let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, instance.args); + let self_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); + instance.args = tcx.mk_args_trait(self_ty, trait_ref.args.into_iter().skip(1)); + instance } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index bebfd746e1f6b..e2be87e6b271f 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -5,7 +5,6 @@ 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 fb9f242f60085..e0d9d6976bd14 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -14,7 +14,6 @@ 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 b2b57e018a7cf..eada6d2457e75 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -61,7 +61,6 @@ use rustc_hir::intravisit::Visitor; 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 2a3ddaa54aadd..a024cf78c8be1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -11,7 +11,6 @@ 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 0b7cbd5f931e6..d5e01be7fe2c6 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 @@ -25,7 +25,6 @@ use rustc_infer::traits::{ImplSource, TraitErrors, WellFormedLoc}; 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 cc5375cb334c1..f30719ffce924 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,7 +4,6 @@ use rustc_attr_ir::diagnostic::{CustomDiagnostic, FilterOptions, FormatArgs}; use rustc_attr_ir::find_attr; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -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 b3ac3d179c8e8..5d508c73086f9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -24,7 +24,6 @@ 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 83f1fcd756981..ba480654bd84a 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -11,7 +11,6 @@ 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 8ad7fd4ac3a69..aa676dab91bbc 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -30,7 +30,6 @@ 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 31d2e8620af90..e9e1cea48ba20 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -2,7 +2,6 @@ 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 c0ffc8babc723..e02337a421848 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -31,7 +31,6 @@ pub struct Assume { #[cfg(feature = "rustc")] mod rustc { use rustc_attr_ir::lang_items::LangItem; - use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::transmute::Answer; use rustc_middle::ty::{Const, Region, Ty, TyCtxt}; diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 79369e5715d21..0507265ded631 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -5,7 +5,6 @@ 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, bug}; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index cb68b8032f7e1..4fd92194c5d81 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -6,6 +6,7 @@ use std::fmt::Debug; use std::hash::Hash; +use rustc_abi::Size; use rustc_ast_ir::Mutability; use crate::elaborate::Elaboratable; @@ -231,8 +232,10 @@ pub trait Safety>: Copy + Debug + Hash + Eq { #[rust_analyzer::prefer_underscore_import] pub trait ValueConst>: Copy + Debug + Hash + Eq { + fn new(ty: I::Ty, valtree: I::ValTree) -> Self; fn ty(self) -> I::Ty; fn valtree(self) -> I::ValTree; + fn try_to_target_usize(self, interner: I) -> Option; } #[rust_analyzer::prefer_underscore_import] @@ -747,3 +750,13 @@ pub trait RegionName: Copy + Hash + PartialEq + Eq + Debug { pub trait DefIdGetter: Copy + Hash + PartialEq + Eq + Debug { fn get_def_id(self) -> Option; } + +pub trait ScalarInt: Copy + Debug + Hash + Eq { + fn to_scalar(self) -> I::Scalar; + fn try_from_uint(i: impl Into, size: Size) -> Option; +} + +pub trait TypingEnv: Copy + Clone + Debug + PartialEq + Eq + Hash { + fn fully_monomorphized() -> Self; + fn layout_size(self, interner: I, ty: I::Ty) -> Size; +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 1bfaa869cbabb..159c2939875b0 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -22,7 +22,8 @@ use crate::solve::{ use crate::visit::{Flags, TypeVisitable}; use crate::{ self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, Const, ConstKind, - DebruijnIndex, Region, RegionKind, RegionVid, TraitRef, WithCachedTypeInfo, search_graph, + DebruijnIndex, Region, RegionKind, RegionVid, TraitRef, ValTreeKind, WithCachedTypeInfo, + search_graph, }; /// The central trait in the shared abstraction layer, specifying all implementation-specific @@ -117,6 +118,7 @@ pub trait Interner: type Term: Term; type BoundVarKinds: BoundVarKinds; + type TypingEnv: TypingEnv; type PredefinedOpaques: Copy + Debug @@ -207,7 +209,8 @@ pub trait Interner: type ValueConst: ValueConst + TypeFoldable + Display; type ExprConst: ExprConst; type ValTree: Copy + Debug + Hash + Eq + IntoKind>; - type ScalarInt: Copy + Debug + Hash + Eq; + type ScalarInt: ScalarInt; + type Scalar: Copy + Debug + Hash + Eq; // Kinds of regions /// (2026/08/13) @@ -548,8 +551,12 @@ pub trait Interner: fn intern_canonical_bound(self, var: BoundVar) -> Region; + fn intern_valtree(self, valtree_kind: ValTreeKind) -> Self::ValTree; + type CanonicalInput: Copy + Debug + Hash + Eq + Deref>; fn mk_canonical_input(self, data: CanonicalInputData) -> Self::CanonicalInput; + + fn const_zst(self) -> Self::ValTree; } macro_rules! declare_lift_into { diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a6bf66f0909fc..55fb628e1ee3e 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -233,7 +233,7 @@ impl RerunCondition { | ( Self::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(a), Self::AnyOpaqueHasInferAsHidden, - ) => Self::OpaqueInStorage(a), + ) => Self::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(a), ( Self::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(a), diff --git a/compiler/rustc_type_ir/src/sty/consts.rs b/compiler/rustc_type_ir/src/sty/consts.rs index da2256078efa7..65cce0aa20481 100644 --- a/compiler/rustc_type_ir/src/sty/consts.rs +++ b/compiler/rustc_type_ir/src/sty/consts.rs @@ -9,10 +9,12 @@ use rustc_type_ir_macros::{GenericTypeVisitable, Lift_Generic}; use crate::inherent::*; use crate::intern::Interned; use crate::relate::{Relate, RelateResult, TypeRelation}; +use crate::walk::TypeWalker; use crate::{ AliasConst, BoundConst, BoundVar, BoundVarIndexKind, ConstKind, ConstVid, DebruijnIndex, FallibleTypeFolder, Flags, InferConst, Interner, IsRigid, PlaceholderConst, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, + ValTreeKind, }; #[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)] @@ -145,6 +147,119 @@ impl Const { _ => None, } } + + #[inline] + pub fn new_value(interner: I, valtree: I::ValTree, ty: I::Ty) -> Self { + Self::new(interner, ConstKind::Value(I::ValueConst::new(ty, valtree))) + } + + /// Creates an interned zst constant. + #[inline] + pub fn zero_sized(interner: I, ty: I::Ty) -> Self { + Self::new_value(interner, interner.const_zst(), ty) + } + + /// Panics if `self.kind != ty::ConstKind::Value`. + pub fn to_value(self) -> I::ValueConst { + match self.kind() { + ConstKind::Value(cv) => cv, + _ => panic!("expected ConstKind::Value, got {:?}", self.kind()), + } + } + + /// Attempts to convert to a value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_value(self) -> Option { + match self.kind() { + ConstKind::Value(cv) => Some(cv), + _ => None, + } + } + + /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing + /// if this constant is some other kind. + /// + /// Note that this does not normalize the constant. + #[inline] + pub fn to_leaf(self) -> I::ScalarInt { + self.to_value().valtree().kind().to_leaf() + } + + /// Converts to a `ValTreeKind::Branch` value, `panic`'ing + /// if this constant is some other kind. + /// + /// Note that this does not normalize the constant. + #[inline] + pub fn to_branch(self) -> I::Consts { + self.to_value().valtree().kind().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 { + self.try_to_value()?.valtree().kind().try_to_leaf() + } + /// Attempts to convert to a `ValTreeKind::Branch` value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_branch(self) -> Option { + self.try_to_value()?.valtree().kind().try_to_branch() + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_scalar(self) -> Option { + self.try_to_leaf().map(|x| x.to_scalar()) + } + + /// Creates a constant with the given integer value and interns it. + #[inline] + pub fn from_bits(interner: I, bits: u128, typing_env: I::TypingEnv, ty: I::Ty) -> Self { + let size = typing_env.layout_size(interner, ty); + let scalar_int = I::ScalarInt::try_from_uint(bits, size).unwrap(); + let valtree = interner.intern_valtree(ValTreeKind::Leaf(scalar_int)); + Self::new_value(interner, valtree, ty) + } + + #[inline] + /// Creates an interned bool constant. + pub fn from_bool(interner: I, v: bool) -> Self { + let bool_ty = I::Ty::new_bool(interner); + Self::from_bits(interner, v as u128, I::TypingEnv::fully_monomorphized(), bool_ty) + } + + #[inline] + /// Creates an interned usize constant. + pub fn from_target_usize(interner: I, n: u64) -> Self { + let usize_ty = I::Ty::new_usize(interner); + Self::from_bits(interner, n as u128, I::TypingEnv::fully_monomorphized(), usize_ty) + } + + /// Convenience method to extract the value of a usize constant, + /// useful to get the length of an array type. + /// + /// Note that this does not evaluate the constant. + #[inline] + pub fn try_to_target_usize(self, interner: I) -> Option { + self.try_to_value()?.try_to_target_usize(interner) + } + + /// 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 + /// structs or variants. For example: + /// + /// ```text + /// isize => { isize } + /// Foo> => { Foo>, Bar, isize } + /// [isize] => { [isize], isize } + /// ``` + pub fn walk(self) -> TypeWalker { + TypeWalker::new(self.into()) + } } impl Flags for Const { diff --git a/library/core/src/keyword_docs.rs b/library/core/src/keyword_docs.rs index 2ea028ef8439d..c2fcb790a3e68 100644 --- a/library/core/src/keyword_docs.rs +++ b/library/core/src/keyword_docs.rs @@ -1295,7 +1295,7 @@ const _: () = (); /// /// Example of using `become` to implement functional-style `fold`: /// -/// ```ignore-wasm (tail-call target feature not enabled by default on wasm) +/// ```ignore-wasm,ignore-powerpc,ignore-powerpc64 (tail-call target feature not enabled by default on wasm, PowerPC tail calls are not implemented in LLVM) /// #![feature(explicit_tail_calls)] /// #![expect(incomplete_features)] /// @@ -1350,7 +1350,7 @@ const _: () = (); /// /// It is possible to tail-call a function pointer: /// -/// ```ignore-wasm (tail-call target feature not enabled by default on wasm) +/// ```ignore-wasm,ignore-powerpc,ignore-powerpc64 (tail-call target feature not enabled by default on wasm, PowerPC tail calls are not implemented in LLVM) /// #![feature(explicit_tail_calls)] /// #![expect(incomplete_features)] /// diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index 4b5b80ed3036c..107ab36741b2b 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -6,7 +6,6 @@ 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 as _; 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 e39fe76715e3a..4d8ef09d17da3 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Ty, Unnormalized}; use rustc_span::{BytePos, Pos as _, Span}; 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 3c58425e2621b..49d4fe478cdf4 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -8,7 +8,6 @@ use clippy_utils::{is_from_proc_macro, sym}; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::ty; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Span; 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 ae56293a77b05..ba2a418104a47 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 @@ -13,7 +13,6 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::{self, EarlyBinder, Ty}; pub(super) fn check( 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 19085c5ffa687..ec0c4fb23390b 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs @@ -11,7 +11,6 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::walk_block; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Pat, PatKind, StmtKind}; use rustc_lint::LateContext; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; use std::fmt::Display; 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 ee9f26b7961f8..0b72fe6507568 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,7 +15,6 @@ 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 as _; 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 6343c13a20eb8..3d9a634f2008f 100644 --- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs @@ -11,7 +11,6 @@ use rustc_hir::def::{DefKind, Res}; 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::consts::ConstExt as _; use rustc_middle::ty::{self, AdtDef, TyCtxt, TypeckResults, VariantDef}; use rustc_span::Span; 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 88fb32752ef04..7ec9021af11d8 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 @@ -6,7 +6,6 @@ use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_middle::ty::consts::ConstExt as _; 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 28d9baa80fe5f..9e7764fa19c80 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -4,7 +4,6 @@ use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, QPath, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::{self, Ty}; 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 94ea802085ccb..9fa66fc86c305 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -3,7 +3,6 @@ use clippy_utils::{has_repr_attr, is_in_test}; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_middle::ty; -use rustc_middle::ty::consts::ConstExt as _; declare_clippy_lint! { /// ### What it does 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 3af5bab642fb4..fe64f06e0633e 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -13,7 +13,6 @@ use rustc_data_structures::packed::Pu128; use rustc_hir::intravisit::Visitor; use rustc_hir::{Arm, Expr, ExprKind, HirId, ImplItemKind, ItemKind, Node, PatKind, Stmt, TraitFn, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::sym; diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 239cf7cae8bf2..2cb2ffa5a856d 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -21,7 +21,6 @@ use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::interpret::{Scalar, alloc_range}; use rustc_middle::mir::{self, ConstValue}; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::{self, FloatTy, IntTy, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy}; use rustc_span::{Symbol, SyntaxContext, bug, span_bug}; use std::cell::Cell; diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 0613d8d7453af..450c991dcd9e9 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -21,7 +21,6 @@ use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::Scalar; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind}; -use rustc_middle::ty::consts::ConstExt as _; use rustc_middle::ty::layout::{LayoutError, LayoutOf as _, TyAndLayout}; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg, diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 2b19015b9c2b0..a2dc3bb20e8c7 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2394,8 +2394,6 @@ ui/rust-2018/uniform-paths/issue-55779.rs ui/rust-2018/uniform-paths/issue-56596-2.rs ui/rust-2018/uniform-paths/issue-56596.rs ui/rust-2018/uniform-paths/issue-87932.rs -ui/sanitizer/issue-111184-cfi-coroutine-witness.rs -ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs ui/sanitizer/issue-72154-address-lifetime-markers.rs ui/self/issue-61882-2.rs ui/self/issue-61882.rs diff --git a/tests/ui/associated-types/issue-67684.rs b/tests/ui/associated-types/issue-67684.rs index 3122c670b4406..d83c1d0bbb33a 100644 --- a/tests/ui/associated-types/issue-67684.rs +++ b/tests/ui/associated-types/issue-67684.rs @@ -1,10 +1,17 @@ -//@ revisions: check build -//@ [check]check-pass +//@ revisions: check build next_ice +//@[check] check-pass // // This second configuration aims to verify that we do not ICE in ConstProp because of // normalization failure. -//@ [build]build-pass -//@ [build]compile-flags: -Zmir-opt-level=3 --emit=mir +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next_ice] compile-flags: -Znext-solver +//@[next_ice] known-bug: #163817 +//@[next_ice] failure-status: 101 +//@[next_ice] dont-check-compiler-stderr +//@[next_ice] needs-rustc-debug-assertions +//@[next_ice] compile-flags: -Zmir-opt-level=3 --emit=mir +//@[build] build-pass +//@[build] compile-flags: -Zmir-opt-level=3 --emit=mir #![allow(dead_code)] diff --git a/tests/ui/const-generics/gca/reported-abi-error-issue-162814.default.stderr b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.default.stderr new file mode 100644 index 0000000000000..06b5b5d0ebcce --- /dev/null +++ b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.default.stderr @@ -0,0 +1,14 @@ +error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[u8; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here + +note: the above error was encountered while instantiating `fn trigger::<[u8; usize::MAX]>` + --> $DIR/reported-abi-error-issue-162814.rs:26:5 + | +LL | trigger::<[u8; usize::MAX]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/const-generics/gca/reported-abi-error-issue-162814.optimized.stderr b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.optimized.stderr new file mode 100644 index 0000000000000..994e43854f825 --- /dev/null +++ b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.optimized.stderr @@ -0,0 +1,8 @@ +error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[u8; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/const-generics/gca/reported-abi-error-issue-162814.rs b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.rs new file mode 100644 index 0000000000000..9bcf19d77b298 --- /dev/null +++ b/tests/ui/const-generics/gca/reported-abi-error-issue-162814.rs @@ -0,0 +1,27 @@ +//@ build-fail +//@ revisions: default optimized +//@ compile-flags: -Znext-solver +//@[optimized] compile-flags: -O +//@ normalize-stderr: "(?m)^ ::: \$SRC_DIR/core/src/mem/mod\.rs:LL:COL\n" -> "" +#![feature(gca_min_const_items, generic_const_items, gca_const_items)] +#![expect(incomplete_features)] + +//~? ERROR too big for the target architecture + +const N: usize = 1 + size_of::(); + +struct Buffer([u8; CAP]); + +impl Buffer { + fn new() -> Self { + Self([0; CAP]) + } +} + +fn trigger() { + let _ = Buffer::<{ core::gca!(N::) }>::new(); +} + +fn main() { + trigger::<[u8; usize::MAX]>(); +} diff --git a/tests/ui/derives/attr-macro-changes-type-kind.rs b/tests/ui/derives/attr-macro-changes-type-kind.rs index 98e05af3b33b6..e655e525a1046 100644 --- a/tests/ui/derives/attr-macro-changes-type-kind.rs +++ b/tests/ui/derives/attr-macro-changes-type-kind.rs @@ -8,7 +8,7 @@ extern crate struct_to_enum; use struct_to_enum::*; -#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] #[struct_to_enum::phantom] struct Spooky; diff --git a/tests/ui/derives/default/attr-macros-fieldless-types.rs b/tests/ui/derives/default/attr-macros-fieldless-types.rs new file mode 100644 index 0000000000000..9a2e68c50551d --- /dev/null +++ b/tests/ui/derives/default/attr-macros-fieldless-types.rs @@ -0,0 +1,47 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/164078, +//! where some attribute macros relied on the generated code always being +//! `Unit {}` and not `Unit()` or `Unit`. + +//@ check-pass +//@ proc-macro: rewrite-fieldless-type-kind.rs + +extern crate rewrite_fieldless_type_kind; +use rewrite_fieldless_type_kind::*; + +#[derive(Default)] +#[to_unit] +struct UnitToUnit; + +#[derive(Default)] +#[to_tuple] +struct UnitToTuple; + +#[derive(Default)] +#[to_braced] +struct UnitToBraced; + +#[derive(Default)] +#[to_unit] +struct TupleToUnit(); + +#[derive(Default)] +#[to_tuple] +struct TupleToTuple(); + +#[derive(Default)] +#[to_braced] +struct TupleToBraced(); + +#[derive(Default)] +#[to_unit] +struct BracedToUnit {} + +#[derive(Default)] +#[to_tuple] +struct BracedToTuple {} + +#[derive(Default)] +#[to_braced] +struct BracedToBraced {} + +fn main() {} diff --git a/tests/ui/derives/default/auxiliary/rewrite-fieldless-type-kind.rs b/tests/ui/derives/default/auxiliary/rewrite-fieldless-type-kind.rs new file mode 100644 index 0000000000000..f75a03cdba647 --- /dev/null +++ b/tests/ui/derives/default/auxiliary/rewrite-fieldless-type-kind.rs @@ -0,0 +1,20 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn to_unit(_: TokenStream, struct_item: TokenStream) -> TokenStream { + rewrite(struct_item, ";") +} +#[proc_macro_attribute] +pub fn to_tuple(_: TokenStream, struct_item: TokenStream) -> TokenStream { + rewrite(struct_item, "();") +} +#[proc_macro_attribute] +pub fn to_braced(_: TokenStream, struct_item: TokenStream) -> TokenStream { + rewrite(struct_item, "{}") +} + +fn rewrite(struct_item: TokenStream, suffix: &str) -> TokenStream { + let ident = struct_item.into_iter().nth(1).unwrap(); + format!("struct {ident}{suffix}").parse().unwrap() +} diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 163658d2106dd..865c6e20da91c 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -46,7 +46,7 @@ impl ::core::fmt::Debug for Empty { #[automatically_derived] impl ::core::default::Default for Empty { #[inline] - fn default() -> Self { Empty } + fn default() -> Self { Empty {} } } #[automatically_derived] impl ::core::hash::Hash for Empty { diff --git a/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs b/tests/ui/sanitizer/cfi/const-expr-in-array-len-issue-114275.rs similarity index 100% rename from tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs rename to tests/ui/sanitizer/cfi/const-expr-in-array-len-issue-114275.rs diff --git a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs b/tests/ui/sanitizer/cfi/coroutine-witness-issue-111184.rs similarity index 100% rename from tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs rename to tests/ui/sanitizer/cfi/coroutine-witness-issue-111184.rs index ac2b95b639820..e47d3b7c608bf 100644 --- a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs +++ b/tests/ui/sanitizer/cfi/coroutine-witness-issue-111184.rs @@ -6,8 +6,8 @@ //@ edition: 2021 //@ no-prefer-dynamic //@ only-x86_64-unknown-linux-gnu -//@ build-pass //@ ignore-backends: gcc +//@ build-pass use std::future::Future; diff --git a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs b/tests/ui/sanitizer/cfi/reveal-opaques-issue-114160.rs similarity index 88% rename from tests/ui/sanitizer/cfi/can-reveal-opaques.rs rename to tests/ui/sanitizer/cfi/reveal-opaques-issue-114160.rs index 310ce04c55240..3d9e70b8d7149 100644 --- a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs +++ b/tests/ui/sanitizer/cfi/reveal-opaques-issue-114160.rs @@ -1,3 +1,6 @@ +// Regression test for issue 114160, where the return type of the call could not be normalized +// with a user-facing param-env, causing an ICE. (See the comment in main for the details.) +// //@ needs-sanitizer-cfi //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer //@ no-prefer-dynamic @@ -5,8 +8,6 @@ //@ ignore-backends: gcc //@ build-pass -// See comment below for why this test exists. - trait Tr { type Projection; } diff --git a/tests/ui/sanitizer/split-lto-unit-requires-lto.rs b/tests/ui/sanitizer/cfi/split-lto-unit-requires-lto.rs similarity index 100% rename from tests/ui/sanitizer/split-lto-unit-requires-lto.rs rename to tests/ui/sanitizer/cfi/split-lto-unit-requires-lto.rs diff --git a/tests/ui/sanitizer/split-lto-unit-requires-lto.stderr b/tests/ui/sanitizer/cfi/split-lto-unit-requires-lto.stderr similarity index 100% rename from tests/ui/sanitizer/split-lto-unit-requires-lto.stderr rename to tests/ui/sanitizer/cfi/split-lto-unit-requires-lto.stderr diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs b/tests/ui/sanitizer/kcfi/arity-requires-kcfi.rs similarity index 100% rename from tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs rename to tests/ui/sanitizer/kcfi/arity-requires-kcfi.rs diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr b/tests/ui/sanitizer/kcfi/arity-requires-kcfi.stderr similarity index 100% rename from tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr rename to tests/ui/sanitizer/kcfi/arity-requires-kcfi.stderr