diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index dd9ebf298b229..84c1e8e6f3d47 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -2086,7 +2086,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_splat { - let (_out_len, out_ty) = require_simd!(ret_ty, SimdReturn); + let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn); require!( args[0].layout.ty == out_ty, @@ -2105,7 +2105,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // `shufflevector v0, poison, zeroinitializer` // The masks is all zeros, so this splats lane 0 (which has our element in it). - let splat = bx.shuffle_vector(v0, poison_vec, bx.const_null(llret_ty)); + let mask_ty = bx.type_vector(bx.type_i32(), out_len); + let splat = bx.shuffle_vector(v0, poison_vec, bx.const_null(mask_ty)); return Ok(splat); } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 50d58e020601d..fefbf6adfd132 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -2,7 +2,7 @@ use std::borrow::{Borrow, Cow}; use std::hash::Hash; use std::{fmt, mem}; -use rustc_abi::{Align, FIRST_VARIANT, Size}; +use rustc_abi::{Align, FIRST_VARIANT, FieldIdx, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -11,7 +11,7 @@ use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement}; -use rustc_middle::ty::{self, FieldInfo, Ty, TyCtxt}; +use rustc_middle::ty::{self, FieldInfo, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_target::callconv::FnAbi; @@ -605,6 +605,23 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { ecx.write_type_info(ty, dest)?; } + sym::size_of_type_id => { + let ty = ecx.read_type_id(&args[0])?; + let layout = ecx.layout_of(ty)?; + let variant_index = if layout.is_sized() { + let (variant, variant_place) = ecx.project_downcast_named(dest, sym::Some)?; + let size_field_place = ecx.project_field(&variant_place, FieldIdx::ZERO)?; + ecx.write_scalar( + ScalarInt::try_from_target_usize(layout.size.bytes(), ecx.tcx.tcx).unwrap(), + &size_field_place, + )?; + variant + } else { + ecx.project_downcast_named(dest, sym::None)?.0 + }; + ecx.write_discriminant(variant_index, dest)?; + } + sym::field_offset => { let frt_ty = instance.args.type_at(0); ensure_monomorphic_enough(ecx.tcx.tcx, frt_ty)?; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 7b63ab5bb02e8..3d8d9592459c4 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -2,7 +2,7 @@ mod adt; use std::borrow::Cow; -use rustc_abi::{ExternAbi, FieldIdx, VariantIdx}; +use rustc_abi::{ExternAbi, FieldIdx}; use rustc_ast::Mutability; use rustc_hir::LangItem; use rustc_middle::span_bug; @@ -12,27 +12,11 @@ use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; use crate::interpret::{ - CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Projectable, Scalar, - Writeable, interp_ok, + CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Scalar, Writeable, + interp_ok, }; impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { - /// Equivalent to `project_downcast`, but identifies the variant by name instead of index. - fn downcast<'a>( - &self, - place: &(impl Writeable<'tcx, CtfeProvenance> + 'a), - name: Symbol, - ) -> InterpResult<'tcx, (VariantIdx, impl Writeable<'tcx, CtfeProvenance> + 'a)> { - let variants = place.layout().ty.ty_adt_def().unwrap().variants(); - let variant_idx = variants - .iter_enumerated() - .find(|(_idx, var)| var.name == name) - .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) - .0; - - interp_ok((variant_idx, self.project_downcast(place, variant_idx)?)) - } - // A general method to write an array to a static slice place. fn allocate_fill_and_write_slice_ptr( &mut self, @@ -83,7 +67,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { let variant_index = match ty.kind() { ty::Tuple(fields) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Tuple)?; + self.project_downcast_named(&field_dest, sym::Tuple)?; // project to the single tuple variant field of `type_info::Tuple` struct type let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?; assert_eq!( @@ -102,7 +86,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::Array(ty, len) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Array)?; + self.project_downcast_named(&field_dest, sym::Array)?; let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_array_type_info(array_place, *ty, *len)?; @@ -111,7 +95,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::Slice(ty) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Slice)?; + self.project_downcast_named(&field_dest, sym::Slice)?; let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_slice_type_info(slice_place, *ty)?; @@ -123,16 +107,17 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::Bool => { let (variant, _variant_place) = - self.downcast(&field_dest, sym::Bool)?; + self.project_downcast_named(&field_dest, sym::Bool)?; variant } ty::Char => { let (variant, _variant_place) = - self.downcast(&field_dest, sym::Char)?; + self.project_downcast_named(&field_dest, sym::Char)?; variant } ty::Int(int_ty) => { - let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; + let (variant, variant_place) = + self.project_downcast_named(&field_dest, sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_int_type_info( place, @@ -142,7 +127,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Uint(uint_ty) => { - let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; + let (variant, variant_place) = + self.project_downcast_named(&field_dest, sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_int_type_info( place, @@ -153,18 +139,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::Float(float_ty) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Float)?; + self.project_downcast_named(&field_dest, sym::Float)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_float_type_info(place, float_ty.bit_width())?; variant } ty::Str => { - let (variant, _variant_place) = self.downcast(&field_dest, sym::Str)?; + let (variant, _variant_place) = + self.project_downcast_named(&field_dest, sym::Str)?; variant } ty::Ref(_, ty, mutability) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Reference)?; + self.project_downcast_named(&field_dest, sym::Reference)?; let reference_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_reference_type_info(reference_place, *ty, *mutability)?; @@ -173,7 +160,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::RawPtr(ty, mutability) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::Pointer)?; + self.project_downcast_named(&field_dest, sym::Pointer)?; let pointer_place = self.project_field(&variant_place, FieldIdx::ZERO)?; @@ -183,14 +170,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } ty::Dynamic(predicates, region) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::DynTrait)?; + self.project_downcast_named(&field_dest, sym::DynTrait)?; let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?; variant } ty::FnPtr(sig, fn_header) => { let (variant, variant_place) = - self.downcast(&field_dest, sym::FnPtr)?; + self.project_downcast_named(&field_dest, sym::FnPtr)?; let fn_ptr_place = self.project_field(&variant_place, FieldIdx::ZERO)?; @@ -214,27 +201,10 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(..) - | ty::Error(_) => self.downcast(&field_dest, sym::Other)?.0, + | ty::Error(_) => self.project_downcast_named(&field_dest, sym::Other)?.0, }; self.write_discriminant(variant_index, &field_dest)? } - sym::size => { - let layout = self.layout_of(ty)?; - let variant_index = if layout.is_sized() { - let (variant, variant_place) = self.downcast(&field_dest, sym::Some)?; - let size_field_place = - self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_scalar( - ScalarInt::try_from_target_usize(layout.size.bytes(), self.tcx.tcx) - .unwrap(), - &size_field_place, - )?; - variant - } else { - self.downcast(&field_dest, sym::None)?.0 - }; - self.write_discriminant(variant_index, &field_dest)?; - } other => span_bug!(self.tcx.span, "unknown `Type` field {other}"), } } @@ -433,16 +403,17 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { sym::abi => match fn_sig_kind.abi() { ExternAbi::C { .. } => { let (rust_variant, _rust_place) = - self.downcast(&field_place, sym::ExternC)?; + self.project_downcast_named(&field_place, sym::ExternC)?; self.write_discriminant(rust_variant, &field_place)?; } ExternAbi::Rust => { let (rust_variant, _rust_place) = - self.downcast(&field_place, sym::ExternRust)?; + self.project_downcast_named(&field_place, sym::ExternRust)?; self.write_discriminant(rust_variant, &field_place)?; } other_abi => { - let (variant, variant_place) = self.downcast(&field_place, sym::Named)?; + let (variant, variant_place) = + self.project_downcast_named(&field_place, sym::Named)?; let str_place = self.allocate_str_dedup(other_abi.as_str())?; let str_ref = self.mplace_to_imm_ptr(&str_place, None)?; let payload = self.project_field(&variant_place, FieldIdx::ZERO)?; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs index 2143313bbbada..9016064de8fd4 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs @@ -22,7 +22,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { let (adt_ty, adt_def) = adt; let variant_idx = match adt_def.adt_kind() { AdtKind::Struct => { - let (variant, variant_place) = self.downcast(place, sym::Struct)?; + let (variant, variant_place) = self.project_downcast_named(place, sym::Struct)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_struct_type_info( place, @@ -32,7 +32,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } AdtKind::Union => { - let (variant, variant_place) = self.downcast(place, sym::Union)?; + let (variant, variant_place) = self.project_downcast_named(place, sym::Union)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_union_type_info( place, @@ -42,7 +42,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } AdtKind::Enum => { - let (variant, variant_place) = self.downcast(place, sym::Enum)?; + let (variant, variant_place) = self.project_downcast_named(place, sym::Enum)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_enum_type_info(place, adt, generics)?; variant @@ -219,13 +219,13 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { _region: Region<'tcx>, place: MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { - let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?; + let (variant_idx, _) = self.project_downcast_named(&place, sym::Lifetime)?; self.write_discriminant(variant_idx, &place)?; interp_ok(()) } fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { - let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?; + let (variant_idx, variant_place) = self.project_downcast_named(&place, sym::Type)?; let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?; for (field_idx, field_def) in generic_type_place @@ -251,7 +251,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") }; - let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?; + let (variant_idx, variant_place) = self.project_downcast_named(&place, sym::Const)?; let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?; for (field_idx, field_def) in const_place diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index db72c02e308c0..27f91b2b89b2c 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -14,6 +14,7 @@ use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, mir, span_bug, ty}; +use rustc_span::Symbol; use tracing::{debug, instrument}; use super::{ @@ -227,6 +228,22 @@ where base.offset(Size::ZERO, layout, self) } + /// Equivalent to `project_downcast`, but identifies the variant by name instead of index. + pub fn project_downcast_named>( + &self, + base: &P, + name: Symbol, + ) -> InterpResult<'tcx, (VariantIdx, P)> { + let variants = base.layout().ty.ty_adt_def().unwrap().variants(); + let variant_idx = variants + .iter_enumerated() + .find(|(_idx, var)| var.name == name) + .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) + .0; + + interp_ok((variant_idx, self.project_downcast(base, variant_idx)?)) + } + /// Compute the offset and field layout for accessing the given index. pub fn project_index>( &self, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 7d606439cedc3..d0bb68c5bc33b 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -199,6 +199,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::sinf64 | sym::sinf128 | sym::size_of + | sym::size_of_type_id | sym::sqrtf16 | sym::sqrtf32 | sym::sqrtf64 @@ -281,6 +282,7 @@ pub(crate) fn check_intrinsic_type( let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]).skip_norm_wip(); (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty) }; + let type_id_ty = || tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(); let safety = intrinsic_operation_unsafety(tcx, intrinsic_id); let n_lts = 0; @@ -294,6 +296,7 @@ pub(crate) fn check_intrinsic_type( sym::size_of_val | sym::align_of_val => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize) } + sym::size_of_type_id => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, tcx.types.usize)), sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize), sym::field_offset => (1, 0, vec![], tcx.types.usize), sym::rustc_peek => (1, 0, vec![param(0)], param(0)), @@ -313,16 +316,8 @@ pub(crate) fn check_intrinsic_type( sym::needs_drop => (1, 0, vec![], tcx.types.bool), sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)), - sym::type_id => ( - 1, - 0, - vec![], - tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(), - ), - sym::type_id_eq => { - let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(); - (0, 0, vec![type_id, type_id], tcx.types.bool) - } + sym::type_id => (1, 0, vec![], type_id_ty()), + sym::type_id_eq => (0, 0, vec![type_id_ty(), type_id_ty()], tcx.types.bool), sym::type_id_vtable => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span); let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata); @@ -335,17 +330,12 @@ pub(crate) fn check_intrinsic_type( let option_args = tcx.mk_args(&[dyn_ty.into()]); let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args); - ( - 0, - 0, - vec![tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(); 2], - ret_ty, - ) + (0, 0, vec![type_id_ty(); 2], ret_ty) } sym::type_of => ( 0, 0, - vec![tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap()], + vec![type_id_ty()], tcx.type_of(tcx.lang_items().type_struct().unwrap()).no_bound_vars().unwrap(), ), sym::offload => ( diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index a00fb59963ac2..cbd6afd68473a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -261,7 +261,8 @@ provide! { tcx, def_id, other, cdata, .coerce_unsized_info .get(cdata, def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) - .process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) } + .process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) + } mir_const_qualif => { table } rendered_const => { table } rendered_precise_capturing_args => { table } @@ -300,10 +301,10 @@ provide! { tcx, def_id, other, cdata, Ok(cdata .root .tables - .trait_impl_trait_tys + .collect_return_position_impl_trait_in_trait_tys .get(cdata, def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) - .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) + .process_decoded(tcx, || panic!("{def_id:?} does not have collect_return_position_impl_trait_in_trait_tys"))) } associated_types_for_impl_traits_in_trait_or_impl => { table } @@ -695,6 +696,7 @@ impl CrateStore for CStore { fn as_any(&self) -> &dyn Any { self } + fn untracked_as_any(&mut self) -> &mut dyn Any { self } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 729a0dda7cf3b..57fe9210c6276 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1628,7 +1628,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { - record!(self.tables.trait_impl_trait_tys[def_id] <- table); + record!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); } if let DefKind::Impl { .. } | DefKind::Trait = def_kind { let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c7b2eaa15ebfb..a3645a5556bf3 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -466,7 +466,7 @@ define_tables! { macro_definition: Table>, proc_macro: Table, deduced_param_attrs: Table>, - trait_impl_trait_tys: Table>>>>, + collect_return_position_impl_trait_in_trait_tys: Table>>>>, doc_link_resolutions: Table>, doc_link_traits_in_scope: Table>, assumed_wf_types_for_rpitit: Table, Span)>>, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index de6a105ee2b7b..e12583f38fe72 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -1,7 +1,7 @@ /// This higher-order macro declares a list of types which can be allocated by `Arena`. /// /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type -/// listed. These impls will appear in the implement_ty_decoder! macro. +/// listed. See the `impl_arena_allocatable_decoder!` macro for more. #[macro_export] macro_rules! arena_types { ($macro:path) => ( @@ -9,8 +9,7 @@ macro_rules! arena_types { [] layout: rustc_abi::LayoutData, [] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, [] fn_abi: rustc_target::callconv::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, - // AdtDef are interned and compared by address - [decode] adt_def: rustc_middle::ty::AdtDefData, + [] adt_def: rustc_middle::ty::AdtDefData, [] steal_thir: rustc_data_structures::steal::Steal>, [] steal_mir: rustc_data_structures::steal::Steal>, [decode] mir: rustc_middle::mir::Body<'tcx>, @@ -27,7 +26,7 @@ macro_rules! arena_types { rustc_middle::mir::Body<'tcx> >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [decode] borrowck_result: rustc_data_structures::fx::FxIndexMap< + [] borrowck_result: rustc_data_structures::fx::FxIndexMap< rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, @@ -100,7 +99,7 @@ macro_rules! arena_types { // (during lowering) and the `rustc_middle` arena (for decoding MIR) [decode] asm_template: rustc_ast::InlineAsmTemplatePiece, [decode] used_trait_imports: rustc_data_structures::unord::UnordSet, - [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, + [] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, [] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>, @@ -111,7 +110,7 @@ macro_rules! arena_types { rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, - [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, + [] doc_link_resolutions: rustc_hir::def::DocLinkResMap, [] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, [] mod_child: rustc_middle::metadata::ModChild, [] features: rustc_feature::Features, diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 28bdeabf34dc1..8b1e812582783 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -513,9 +513,8 @@ macro_rules! __impl_decoder_methods { } macro_rules! impl_arena_allocatable_decoder { - ([]$args:tt) => {}; - ([decode $(, $attrs:ident)*] - [$name:ident: $ty:ty]) => { + ([] $name:ident: $ty:ty) => {}; + ([decode] $name:ident: $ty:ty) => { impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { #[inline] fn decode(decoder: &mut D) -> &'tcx Self { @@ -535,7 +534,7 @@ macro_rules! impl_arena_allocatable_decoder { macro_rules! impl_arena_allocatable_decoders { ([$($a:tt $name:ident: $ty:ty,)*]) => { $( - impl_arena_allocatable_decoder!($a [$name: $ty]); + impl_arena_allocatable_decoder!($a $name: $ty); )* } } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index bacddb6808290..1ab8aa7027528 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -8,7 +8,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_span::{DUMMY_SP, Span, Symbol}; -use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; +use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem}; use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, Unnormalized, search_graph}; use crate::dep_graph::{DepKind, DepNodeIndex}; @@ -39,6 +39,20 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type AdtId = DefId; type ImplId = DefId; type UnevaluatedConstId = DefId; + type TraitAssocTyId = DefId; + type TraitAssocConstId = DefId; + type TraitAssocTermId = DefId; + type OpaqueTyId = DefId; + type LocalOpaqueTyId = LocalDefId; + type FreeTyAliasId = DefId; + type FreeConstAliasId = DefId; + type FreeTermAliasId = DefId; + type ImplOrTraitAssocTyId = DefId; + type ImplOrTraitAssocConstId = DefId; + type ImplOrTraitAssocTermId = DefId; + type InherentAssocTyId = DefId; + type InherentAssocConstId = DefId; + type InherentAssocTermId = DefId; type Span = Span; type GenericArgs = ty::GenericArgsRef<'tcx>; @@ -288,7 +302,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.mk_type_list_from_iter(args) } - fn parent(self, def_id: DefId) -> DefId { + fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId { + self.parent(def_id) + } + + fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTyId) -> DefId { + self.parent(def_id) + } + + fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId { self.parent(def_id) } @@ -446,7 +468,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { !self.codegen_fn_attrs(def_id).target_features.is_empty() } - fn require_lang_item(self, lang_item: SolverLangItem) -> DefId { + fn require_projection_lang_item(self, lang_item: SolverProjectionLangItem) -> DefId { self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP) } @@ -458,7 +480,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP) } - fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool { + fn is_projection_lang_item(self, def_id: DefId, lang_item: SolverProjectionLangItem) -> bool { self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item)) } @@ -478,7 +500,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.is_sizedness_trait(def_id) } - fn as_lang_item(self, def_id: DefId) -> Option { + fn as_projection_lang_item(self, def_id: DefId) -> Option { lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?) } @@ -757,7 +779,7 @@ macro_rules! bidirectional_lang_item_map { } bidirectional_lang_item_map! { - SolverLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item; + SolverProjectionLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item; // tidy-alphabetical-start AsyncFnKindUpvars, @@ -766,7 +788,6 @@ bidirectional_lang_item_map! { CallRefFuture, CoroutineReturn, CoroutineYield, - DynMetadata, FieldBase, FieldType, FutureOutput, @@ -778,6 +799,7 @@ bidirectional_lang_item_map! { SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item; // tidy-alphabetical-start + DynMetadata, Option, Poll, // tidy-alphabetical-end @@ -791,7 +813,6 @@ bidirectional_lang_item_map! { AsyncFnKindHelper, AsyncFnMut, AsyncFnOnce, - AsyncFnOnceOutput, AsyncIterator, BikeshedGuaranteedNoDrop, Clone, diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 429206a93dfee..8fd7d6d0471c7 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -69,7 +69,7 @@ pub trait SolverDelegate: Deref + Sized { fn add_item_bounds_for_hidden_type( &self, - def_id: ::DefId, + def_id: ::OpaqueTyId, args: ::GenericArgs, param_env: ::ParamEnv, hidden_ty: ::Ty, @@ -79,7 +79,7 @@ pub trait SolverDelegate: Deref + Sized { fn fetch_eligible_assoc_item( &self, goal_trait_ref: ty::TraitRef, - trait_assoc_def_id: ::DefId, + trait_assoc_def_id: ::TraitAssocTermId, impl_def_id: ::ImplId, ) -> FetchEligibleAssocItemResponse; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 0bbc6f483104f..0053e25e6365a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -4,7 +4,7 @@ use derive_where::derive_where; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::inherent::*; -use rustc_type_ir::lang_items::{SolverLangItem, SolverTraitLangItem}; +use rustc_type_ir::lang_items::{SolverProjectionLangItem, SolverTraitLangItem}; use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{ @@ -106,7 +106,9 @@ where // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - Ok(ty::Binder::dummy(vec![cx.type_of(def_id).instantiate(cx, args).skip_norm_wip()])) + Ok(ty::Binder::dummy(vec![ + cx.type_of(def_id.into()).instantiate(cx, args).skip_norm_wip(), + ])) } } } @@ -541,7 +543,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable( let nested = vec![ bound_sig.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()])).upcast(cx), ]; - let future_output_def_id = cx.require_lang_item(SolverLangItem::FutureOutput); + let future_output_def_id = + cx.require_projection_lang_item(SolverProjectionLangItem::FutureOutput); let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]); Ok(( bound_sig.rebind(AsyncCallableRelevantTypes { @@ -642,7 +646,8 @@ fn coroutine_closure_to_ambiguous_coroutine( args: ty::CoroutineClosureArgs, sig: ty::CoroutineClosureSignature, ) -> I::Ty { - let upvars_projection_def_id = cx.require_lang_item(SolverLangItem::AsyncFnKindUpvars); + let upvars_projection_def_id = + cx.require_projection_lang_item(SolverProjectionLangItem::AsyncFnKindUpvars); let tupled_upvars_ty = Ty::new_projection( cx, upvars_projection_def_id, @@ -920,7 +925,10 @@ where // show up in the bounds, but just ones that come from substituting // `Self` with the dyn type. let proj = proj.with_self_ty(cx, trait_ref.self_ty()); - replace_projection_with.entry(proj.def_id()).or_default().push(bound.rebind(proj)); + replace_projection_with + .entry(proj.def_id().into()) + .or_default() + .push(bound.rebind(proj)); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index e4d3e881f6afc..a03d3182b9fed 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -702,7 +702,7 @@ where original_typing_mode: TypingMode, parent_opaque_types: &[(OpaqueTypeKey, I::Ty)], ) -> RerunDecision { - let parent_opaque_defids = parent_opaque_types.iter().map(|(key, _)| key.def_id); + let parent_opaque_defids = parent_opaque_types.iter().map(|(key, _)| key.def_id.into()); let opaque_in_storage = |opaques: I::LocalDefIds, defids: SmallCopyList<_>| { if defids.as_ref().is_empty() { RerunDecision::No @@ -1357,7 +1357,7 @@ where pub(super) fn fetch_eligible_assoc_item( &self, goal_trait_ref: ty::TraitRef, - trait_assoc_def_id: I::DefId, + trait_assoc_def_id: I::TraitAssocTermId, impl_def_id: I::ImplId, ) -> FetchEligibleAssocItemResponse { self.delegate.fetch_eligible_assoc_item(goal_trait_ref, trait_assoc_def_id, impl_def_id) @@ -1374,7 +1374,7 @@ where pub(super) fn add_item_bounds_for_hidden_type( &mut self, - opaque_def_id: I::DefId, + opaque_def_id: I::OpaqueTyId, opaque_args: I::GenericArgs, param_env: I::ParamEnv, hidden_ty: I::Ty, diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 178a192a66300..5dc3162fbd2a7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -357,7 +357,7 @@ where } } - fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool { + fn opaque_type_is_rigid(&self, def_id: I::OpaqueTyId) -> bool { match self .typing_mode() // Caller should handle erased mode @@ -370,7 +370,7 @@ where TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques } | TypingMode::Borrowck { defining_opaque_types: non_rigid_opaques } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => { - !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id)) + !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id.into())) } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index 72e8d1be5915e..44b8929c45f43 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs @@ -13,6 +13,7 @@ where pub(super) fn normalize_anon_const( &mut self, goal: Goal>, + def_id: I::UnevaluatedConstId, ) -> QueryResult { let uv = goal.predicate.alias.expect_ct(self.cx()); self.evaluate_const_and_instantiate_normalizes_to_term(goal, uv) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs index 44fe2913b73de..f70f4bede33db 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -32,11 +32,13 @@ where let actual = match free_alias.kind(cx) { ty::AliasTermKind::FreeTy { def_id } => { - cx.type_of(def_id).instantiate(cx, free_alias.args).skip_norm_wip().into() - } - ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id) => { - cx.const_of_item(def_id).instantiate(cx, free_alias.args).skip_norm_wip().into() + cx.type_of(def_id.into()).instantiate(cx, free_alias.args).skip_norm_wip().into() } + ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id.into()) => cx + .const_of_item(def_id.into()) + .instantiate(cx, free_alias.args) + .skip_norm_wip() + .into(), ty::AliasTermKind::FreeConst { .. } => { return self.evaluate_const_and_instantiate_normalizes_to_term( goal, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 00b5fd7fdcbce..d9eeb3e90f95f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -18,18 +18,19 @@ where pub(super) fn normalize_inherent_associated_term( &mut self, goal: Goal>, + def_id: I::InherentAssocTermId, ) -> QueryResult { let cx = self.cx(); let inherent = goal.predicate.alias; - let impl_def_id = cx.parent(inherent.def_id()); - let impl_args = self.fresh_args_for_item(impl_def_id); + let impl_def_id = cx.inherent_alias_term_parent(def_id); + let impl_args = self.fresh_args_for_item(impl_def_id.into()); // Equate impl header and add impl where clauses self.eq( goal.param_env, inherent.self_ty(), - cx.type_of(impl_def_id).instantiate(cx, impl_args).skip_norm_wip(), + cx.type_of(impl_def_id.into()).instantiate(cx, impl_args).skip_norm_wip(), )?; // Equate IAT with the RHS of the project goal @@ -46,7 +47,7 @@ where // to be very careful when changing the impl where-clauses to be productive. self.add_goals( GoalSource::Misc, - cx.predicates_of(inherent.def_id()) + cx.predicates_of(def_id.into()) .iter_instantiated(cx, inherent_args) .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), @@ -54,11 +55,13 @@ where let normalized = match inherent.kind(cx) { ty::AliasTermKind::InherentTy { def_id } => { - cx.type_of(def_id).instantiate(cx, inherent_args).skip_norm_wip().into() - } - ty::AliasTermKind::InherentConst { def_id } if cx.is_type_const(def_id) => { - cx.const_of_item(def_id).instantiate(cx, inherent_args).skip_norm_wip().into() + cx.type_of(def_id.into()).instantiate(cx, inherent_args).skip_norm_wip().into() } + ty::AliasTermKind::InherentConst { def_id } if cx.is_type_const(def_id.into()) => cx + .const_of_item(def_id.into()) + .instantiate(cx, inherent_args) + .skip_norm_wip() + .into(), ty::AliasTermKind::InherentConst { .. } => { // FIXME(gca): This is dead code at the moment. It should eventually call // self.evaluate_const like projected consts do in consider_impl_candidate in diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 3b2e13fbb22dc..ce9663666ed90 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -5,7 +5,7 @@ mod opaque_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; -use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; +use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem}; use rustc_type_ir::solve::{FetchEligibleAssocItemResponse, RerunReason}; use rustc_type_ir::{ self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _, @@ -32,74 +32,79 @@ where goal: Goal>, ) -> QueryResult { debug_assert!(self.term_is_fully_unconstrained(goal)); - let cx = self.cx(); - match goal.predicate.alias.kind(cx) { + match goal.predicate.alias.kind { ty::AliasTermKind::ProjectionTy { .. } | ty::AliasTermKind::ProjectionConst { .. } => { - let trait_ref = goal.predicate.alias.trait_ref(cx); - let (_, proven_via) = - self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { - let trait_goal: Goal> = goal.with(cx, trait_ref); - ecx.compute_trait_goal(trait_goal) - })?; - self.assemble_and_merge_candidates( - proven_via, - goal, - |ecx| { - // FIXME(generic_associated_types): Addresses aggressive inference in #92917. - // - // If this type is a GAT with currently unconstrained arguments, we do not - // want to normalize it via a candidate which only applies for a specific - // instantiation. We could otherwise keep the GAT as rigid and succeed this way. - // See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs. - // - // This only avoids normalization if a GAT argument is fully unconstrained. - // This is quite arbitrary but fixing it causes some ambiguity, see #125196. - for arg in goal.predicate.alias.own_args(cx).iter() { - let Some(term) = arg.as_term() else { - continue; - }; - match ecx.structurally_normalize_term(goal.param_env, term) { - Ok(term) => { - if term.is_infer() { - return Some( - ecx.evaluate_added_goals_and_make_canonical_response( - Certainty::AMBIGUOUS, - ), - ); - } - } - Err(NoSolution) => return Some(Err(NoSolution)), - } - } - - None - }, - |ecx| { - ecx.probe(|&result| ProbeKind::RigidAlias { result }) - .enter(|this| { - this.structurally_instantiate_normalizes_to_term( - goal, - goal.predicate.alias, - ); - this.evaluate_added_goals_and_make_canonical_response( - Certainty::Yes, - ) - }) - .map_err(Into::into) - }, - ) + self.normalize_associated_term(goal) } - ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConst { .. } => { - self.normalize_inherent_associated_term(goal) + ty::AliasTermKind::InherentTy { def_id } => { + self.normalize_inherent_associated_term(goal, def_id.into()) } - ty::AliasTermKind::OpaqueTy { .. } => self.normalize_opaque_type(goal), + ty::AliasTermKind::InherentConst { def_id } => { + self.normalize_inherent_associated_term(goal, def_id.into()) + } + ty::AliasTermKind::OpaqueTy { def_id } => self.normalize_opaque_type(goal, def_id), ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::FreeConst { .. } => { self.normalize_free_alias(goal) } - ty::AliasTermKind::UnevaluatedConst { .. } => self.normalize_anon_const(goal), + ty::AliasTermKind::UnevaluatedConst { def_id } => { + self.normalize_anon_const(goal, def_id) + } } } + fn normalize_associated_term(&mut self, goal: Goal>) -> QueryResult { + let cx = self.cx(); + + let trait_ref = goal.predicate.alias.trait_ref(cx); + let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { + let trait_goal: Goal> = goal.with(cx, trait_ref); + ecx.compute_trait_goal(trait_goal) + })?; + self.assemble_and_merge_candidates( + proven_via, + goal, + |ecx| { + // FIXME(generic_associated_types): Addresses aggressive inference in #92917. + // + // If this type is a GAT with currently unconstrained arguments, we do not + // want to normalize it via a candidate which only applies for a specific + // instantiation. We could otherwise keep the GAT as rigid and succeed this way. + // See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs. + // + // This only avoids normalization if a GAT argument is fully unconstrained. + // This is quite arbitrary but fixing it causes some ambiguity, see #125196. + for arg in goal.predicate.alias.own_args(cx).iter() { + let Some(term) = arg.as_term() else { + continue; + }; + match ecx.structurally_normalize_term(goal.param_env, term) { + Ok(term) => { + if term.is_infer() { + return Some(ecx.evaluate_added_goals_and_make_canonical_response( + Certainty::AMBIGUOUS, + )); + } + } + Err(NoSolution) => return Some(Err(NoSolution)), + } + } + + None + }, + |ecx| { + ecx.probe(|&result| ProbeKind::RigidAlias { result }) + .enter(|this| { + this.structurally_instantiate_normalizes_to_term( + goal, + goal.predicate.alias, + ); + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + .map_err(Into::into) + }, + ) + } + /// When normalizing an associated item, constrain the expected term to `term`. /// /// We know `term` to always be a fully unconstrained inference variable, so @@ -282,7 +287,7 @@ where let target_item_def_id = match ecx.fetch_eligible_assoc_item( goal_trait_ref, - goal.predicate.def_id(), + goal.predicate.def_id().try_into().unwrap(), impl_def_id, ) { FetchEligibleAssocItemResponse::Found(target_item_def_id) => target_item_def_id, @@ -354,7 +359,7 @@ where } } - let target_container_def_id = cx.parent(target_item_def_id); + let target_container_def_id = cx.impl_or_trait_assoc_term_parent(target_item_def_id); // Getting the right args here is complex, e.g. given: // - a goal ` as Trait>::Assoc` @@ -371,10 +376,10 @@ where impl_def_id, impl_args, impl_trait_ref, - target_container_def_id, + target_container_def_id.into(), )?; - if !cx.check_args_compatible(target_item_def_id, target_args) { + if !cx.check_args_compatible(target_item_def_id.into(), target_args) { return error_response( ecx, cx.delay_bug("associated item has mismatched arguments"), @@ -384,21 +389,21 @@ where // Finally we construct the actual value of the associated type. let term = match goal.predicate.alias.kind(cx) { ty::AliasTermKind::ProjectionTy { .. } => cx - .type_of(target_item_def_id) + .type_of(target_item_def_id.into()) .instantiate(cx, target_args) .skip_norm_wip() .into(), ty::AliasTermKind::ProjectionConst { .. } - if cx.is_type_const(target_item_def_id) => + if cx.is_type_const(target_item_def_id.into()) => { - cx.const_of_item(target_item_def_id) + cx.const_of_item(target_item_def_id.into()) .instantiate(cx, target_args) .skip_norm_wip() .into() } ty::AliasTermKind::ProjectionConst { .. } => { let uv = ty::UnevaluatedConst::new( - target_item_def_id.try_into().unwrap(), + target_item_def_id.into().try_into().unwrap(), target_args, ); return ecx.evaluate_const_and_instantiate_normalizes_to_term(goal, uv); @@ -504,6 +509,7 @@ where goal_kind: ty::ClosureKind, ) -> Result, NoSolution> { let cx = ecx.cx(); + let def_id = goal.predicate.def_id().try_into().unwrap(); let env_region = match goal_kind { ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2), @@ -531,41 +537,42 @@ where [output_coroutine_ty], ); - let (projection_term, term) = - if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture) { - ( - ty::AliasTerm::new( - cx, - cx.alias_term_kind_from_def_id(goal.predicate.def_id()), - [goal.predicate.self_ty(), tupled_inputs_ty], - ), - output_coroutine_ty.into(), - ) - } else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture) { - ( - ty::AliasTerm::new( - cx, - cx.alias_term_kind_from_def_id(goal.predicate.def_id()), - [ - I::GenericArg::from(goal.predicate.self_ty()), - tupled_inputs_ty.into(), - env_region.into(), - ], - ), - output_coroutine_ty.into(), - ) - } else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput) { - ( - ty::AliasTerm::new( - cx, - cx.alias_term_kind_from_def_id(goal.predicate.def_id()), - [goal.predicate.self_ty(), tupled_inputs_ty], - ), - coroutine_return_ty.into(), - ) - } else { - panic!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id()) - }; + let (projection_term, term) = if cx + .is_projection_lang_item(def_id, SolverProjectionLangItem::CallOnceFuture) + { + ( + ty::AliasTerm::new( + cx, + cx.alias_term_kind_from_def_id(goal.predicate.def_id()), + [goal.predicate.self_ty(), tupled_inputs_ty], + ), + output_coroutine_ty.into(), + ) + } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CallRefFuture) { + ( + ty::AliasTerm::new( + cx, + cx.alias_term_kind_from_def_id(goal.predicate.def_id()), + [ + I::GenericArg::from(goal.predicate.self_ty()), + tupled_inputs_ty.into(), + env_region.into(), + ], + ), + output_coroutine_ty.into(), + ) + } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::AsyncFnOnceOutput) { + ( + ty::AliasTerm::new( + cx, + cx.alias_term_kind_from_def_id(goal.predicate.def_id()), + [goal.predicate.self_ty(), tupled_inputs_ty], + ), + coroutine_return_ty.into(), + ) + } else { + panic!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id()) + }; let pred = ty::ProjectionPredicate { projection_term, term }.upcast(cx); Self::probe_and_consider_implied_clause( @@ -639,8 +646,8 @@ where goal: Goal, ) -> Result, NoSolution> { let cx = ecx.cx(); - let metadata_def_id = cx.require_lang_item(SolverLangItem::Metadata); - assert_eq!(metadata_def_id, goal.predicate.def_id()); + let metadata_def_id = cx.require_projection_lang_item(SolverProjectionLangItem::Metadata); + assert_eq!(Into::::into(metadata_def_id), goal.predicate.def_id()); let metadata_ty = match goal.predicate.self_ty().kind() { ty::Bool | ty::Char @@ -666,8 +673,8 @@ where ty::Str | ty::Slice(_) => Ty::new_usize(cx), ty::Dynamic(_, _) => { - let dyn_metadata = cx.require_lang_item(SolverLangItem::DynMetadata); - cx.type_of(dyn_metadata) + let dyn_metadata = cx.require_adt_lang_item(SolverAdtLangItem::DynMetadata); + cx.type_of(dyn_metadata.into()) .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) .skip_norm_wip() } @@ -865,10 +872,12 @@ where } let coroutine = args.as_coroutine(); + let def_id = goal.predicate.def_id().try_into().unwrap(); - let term = if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CoroutineReturn) { + let term = if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineReturn) + { coroutine.return_ty().into() - } else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CoroutineYield) { + } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineYield) { coroutine.yield_ty().into() } else { panic!("unexpected associated item `{:?}` for `{self_ty:?}`", goal.predicate.def_id()) @@ -992,9 +1001,10 @@ where else { return Err(NoSolution); }; - let ty = match ecx.cx().as_lang_item(goal.predicate.def_id()) { - Some(SolverLangItem::FieldBase) => base, - Some(SolverLangItem::FieldType) => ty, + let ty = match ecx.cx().as_projection_lang_item(goal.predicate.def_id().try_into().unwrap()) + { + Some(SolverProjectionLangItem::FieldBase) => base, + Some(SolverProjectionLangItem::FieldType) => ty, _ => panic!("unexpected associated type {:?} in `Field`", goal.predicate), }; ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index 45dd2f25abd78..f25ac21f4a62b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -17,6 +17,7 @@ where pub(super) fn normalize_opaque_type( &mut self, goal: Goal>, + def_id: I::OpaqueTyId, ) -> QueryResult { let cx = self.cx(); let opaque_ty = goal.predicate.alias; @@ -27,7 +28,7 @@ where // An impossible opaque type bound is the only way this goal will fail // e.g. assigning `impl Copy := NotCopy` self.add_item_bounds_for_hidden_type( - opaque_ty.def_id(), + def_id, opaque_ty.args, goal.param_env, expected, @@ -43,10 +44,9 @@ where defining_opaque_types_and_generators: defining_opaque_types, } | TypingMode::Borrowck { defining_opaque_types } => { - let Some(def_id) = opaque_ty - .def_id() + let Some(def_id) = def_id .as_local() - .filter(|&def_id| defining_opaque_types.contains(&def_id)) + .filter(|&def_id| defining_opaque_types.contains(&def_id.into())) else { // If we're not in the defining scope, treat the alias as rigid. self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); @@ -134,7 +134,7 @@ where TypingMode::PostAnalysis => { // FIXME: Add an assertion that opaque type storage is empty. let actual = - cx.type_of(opaque_ty.def_id()).instantiate(cx, opaque_ty.args).skip_norm_wip(); + cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args).skip_norm_wip(); self.eq(goal.param_env, expected, actual)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 4d5fe3bf69502..a4f35f763e8e2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -242,7 +242,7 @@ where } debug_assert!(ecx.opaque_type_is_rigid(def_id)); - for item_bound in cx.item_self_bounds(def_id).skip_binder() { + for item_bound in cx.item_self_bounds(def_id.into()).skip_binder() { if item_bound .as_trait_clause() .is_some_and(|b| b.def_id() == goal.predicate.def_id()) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3b58ebaf8cc7c..c37838706301a 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -721,13 +721,15 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { decls: Default::default(), nested, id, + def_id: feed.def_id(), }; self.add_import(module_path, kind, use_tree.span(), item, root_span, item.id, vis); } ast::UseTreeKind::Glob(_) => { if !ast::attr::contains_name(&item.attrs, sym::prelude_import) { - let kind = ImportKind::Glob { max_vis: CmCell::new(None), id }; + let kind = + ImportKind::Glob { max_vis: CmCell::new(None), id, def_id: feed.def_id() }; self.add_import(prefix, kind, use_tree.span(), item, root_span, item.id, vis); } else { // Resolve the prelude import early. @@ -1019,7 +1021,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { }) .unwrap_or((true, None, self.r.dummy_decl)); let import = self.r.arenas.alloc_import(ImportData { - kind: ImportKind::ExternCrate { source: orig_name, target: orig_ident, id: item.id }, + kind: ImportKind::ExternCrate { + source: orig_name, + target: orig_ident, + id: item.id, + def_id: local_def_id, + }, root_id: item.id, parent_scope, imported_module: CmCell::new(module), @@ -1271,7 +1278,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { if !ident.as_str().starts_with('_') { self.r.unused_macros.insert(def_id, (node_id, ident)); let nrules = self.r.local_macro_map[&def_id].nrules; - self.r.unused_macro_rules.insert(node_id, DenseBitSet::new_filled(nrules)); + self.r.unused_macro_rules.insert(node_id, (def_id, DenseBitSet::new_filled(nrules))); } } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 7e1b1bce3ff74..8ab0087ae6158 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -431,8 +431,7 @@ impl Resolver<'_, '_> { } } } - ImportKind::ExternCrate { id, .. } => { - let def_id = self.local_def_id(id); + ImportKind::ExternCrate { id, def_id, .. } => { if self.extern_crate_map.get(&def_id).is_none_or(|&cnum| { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index b5614106fe997..693e49995c1cc 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -45,10 +45,7 @@ impl Resolver<'_, '_> { fn private_vis_import(&self, decl: Decl<'_>) -> Visibility { let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; Visibility::Restricted( - import - .id() - .map(|id| self.nearest_normal_mod(self.local_def_id(id))) - .unwrap_or(CRATE_DEF_ID), + import.def_id().map(|id| self.nearest_normal_mod(id)).unwrap_or(CRATE_DEF_ID), ) } @@ -96,8 +93,8 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // is the maximum value among visibilities of declarations corresponding to that def id. for (decl, eff_vis) in visitor.import_effective_visibilities.iter() { let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; - if let Some(node_id) = import.id() { - r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) + if let Some(def_id) = import.def_id() { + r.effective_visibilities.update_eff_vis(def_id, eff_vis, r.tcx) } if decl.ambiguity.get().is_some() && eff_vis.is_public_at_level(Level::Reexported) { exported_ambiguities.insert(*decl); diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index e63ab9f21a6ad..1b9e5d2a2daa6 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -16,7 +16,7 @@ use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; use rustc_hir::def::{self, DefKind, PartialRes}; -use rustc_hir::def_id::{DefId, LocalDefIdMap}; +use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty::{TyCtxt, Visibility}; @@ -90,17 +90,20 @@ pub(crate) enum ImportKind<'ra> { /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree` /// for `a` in this field. id: NodeId, + def_id: LocalDefId, }, Glob { // The visibility of the greatest re-export. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. max_vis: CmCell>, id: NodeId, + def_id: LocalDefId, }, ExternCrate { source: Option, target: Ident, id: NodeId, + def_id: LocalDefId, }, MacroUse { /// A field has been added indicating whether it should be reported as a lint, @@ -116,7 +119,7 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use ImportKind::*; match self { - Single { source, target, decls, nested, id, .. } => f + Single { source, target, decls, nested, id, def_id } => f .debug_struct("Single") .field("source", source) .field("target", target) @@ -127,15 +130,20 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { ) .field("nested", nested) .field("id", id) + .field("def_id", def_id) .finish(), - Glob { max_vis, id } => { - f.debug_struct("Glob").field("max_vis", max_vis).field("id", id).finish() - } - ExternCrate { source, target, id } => f + Glob { max_vis, id, def_id } => f + .debug_struct("Glob") + .field("max_vis", max_vis) + .field("id", id) + .field("def_id", def_id) + .finish(), + ExternCrate { source, target, id, def_id } => f .debug_struct("ExternCrate") .field("source", source) .field("target", target) .field("id", id) + .field("def_id", def_id) .finish(), MacroUse { warn_private } => { f.debug_struct("MacroUse").field("warn_private", warn_private).finish() @@ -260,12 +268,20 @@ impl<'ra> ImportData<'ra> { } } - pub(crate) fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport { - let to_def_id = |id| r.local_def_id(id).to_def_id(); + pub(crate) fn def_id(&self) -> Option { + match self.kind { + ImportKind::Single { def_id, .. } + | ImportKind::Glob { def_id, .. } + | ImportKind::ExternCrate { def_id, .. } => Some(def_id), + ImportKind::MacroUse { .. } | ImportKind::MacroExport => None, + } + } + + pub(crate) fn simplify(&self) -> Reexport { match self.kind { - ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)), - ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)), - ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)), + ImportKind::Single { def_id, .. } => Reexport::Single(def_id.to_def_id()), + ImportKind::Glob { def_id, .. } => Reexport::Glob(def_id.to_def_id()), + ImportKind::ExternCrate { def_id, .. } => Reexport::ExternCrate(def_id.to_def_id()), ImportKind::MacroUse { .. } => Reexport::MacroUse, ImportKind::MacroExport => Reexport::MacroExport, } @@ -340,13 +356,16 @@ struct UnresolvedImportError { // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. -fn pub_use_of_private_extern_crate_hack(import: ImportSummary, decl: Decl<'_>) -> Option { +fn pub_use_of_private_extern_crate_hack( + import: ImportSummary, + decl: Decl<'_>, +) -> Option { match (import.is_single, decl.kind) { (true, DeclKind::Import { import: decl_import, .. }) - if let ImportKind::ExternCrate { id, .. } = decl_import.kind + if let ImportKind::ExternCrate { def_id, .. } = decl_import.kind && import.vis.is_public() => { - Some(id) + Some(def_id) } _ => None, } @@ -845,8 +864,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if binding.res() != Res::Err && glob_decl.res() != Res::Err && let DeclKind::Import { import: glob_import, .. } = glob_decl.kind - && let Some(glob_import_id) = glob_import.id() - && let glob_import_def_id = self.local_def_id(glob_import_id) + && let Some(glob_import_def_id) = glob_import.def_id() && self.effective_visibilities.is_exported(glob_import_def_id) && glob_decl.vis().is_public() && !binding.vis().is_public() @@ -875,7 +893,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let DeclKind::Import { import, .. } = binding.kind && let Some(binding_id) = import.id() - && let import_def_id = self.local_def_id(binding_id) + && let import_def_id = import.def_id().unwrap() && self.effective_visibilities.is_exported(import_def_id) && let Res::Def(reexported_kind, reexported_def_id) = binding.res() && !matches!(reexported_kind, DefKind::Ctor(..)) @@ -1267,7 +1285,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (ident, target, bindings, import_id) = match import.kind { ImportKind::Single { source, target, ref decls, id, .. } => (source, target, decls, id), - ImportKind::Glob { ref max_vis, id } => { + ImportKind::Glob { ref max_vis, id, def_id } => { if import.module_path.len() <= 1 { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. @@ -1294,7 +1312,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(max_vis) = max_vis.get() && import.vis.greater_than(max_vis, self.tcx) { - let def_id = self.local_def_id(id); self.lint_buffer.buffer_lint( UNUSED_IMPORTS, id, @@ -1614,7 +1631,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import.summary(), decl) { let ImportKind::Single { id, .. } = import.kind else { unreachable!() }; - let sugg = self.tcx.source_span(self.local_def_id(extern_crate_id)).shrink_to_lo(); + let sugg = self.tcx.source_span(extern_crate_id).shrink_to_lo(); let diagnostic = crate::errors::PrivateExternCrateReexport { ident, sugg }; return Some(BufferedEarlyLint { lint_id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), @@ -1656,7 +1673,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool { // This function is only called for single imports. - let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else { + let ImportKind::Single { source, target, ref decls, id, def_id, .. } = import.kind else { unreachable!() }; @@ -1675,7 +1692,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Skip if the import is public or was used through non scope-based resolution, // e.g. through a module-relative path. if self.import_use_map.get(&import) == Some(&Used::Other) - || self.effective_visibilities.is_exported(self.local_def_id(id)) + || self.effective_visibilities.is_exported(def_id) { return false; } @@ -1829,23 +1846,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut children = Vec::new(); let mut ambig_children = Vec::new(); - module.to_module().for_each_child(self, |this, ident, orig_ident_span, _, binding| { + module.to_module().for_each_child(self, |_this, ident, orig_ident_span, _, binding| { let res = binding.res().expect_non_local(); if res != def::Res::Err { let ident = ident.orig(orig_ident_span); let child = |reexport_chain| ModChild { ident, res, vis: binding.vis(), reexport_chain }; if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() { - let main = child(ambig_binding1.reexport_chain(this)); + let main = child(ambig_binding1.reexport_chain()); let second = ModChild { ident, res: ambig_binding2.res().expect_non_local(), vis: ambig_binding2.vis(), - reexport_chain: ambig_binding2.reexport_chain(this), + reexport_chain: ambig_binding2.reexport_chain(), }; ambig_children.push(AmbigModChild { main, second }) } else { - children.push(child(binding.reexport_chain(this))); + children.push(child(binding.reexport_chain())); } } }); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 91511cbcb65ab..4352e10462901 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1171,11 +1171,11 @@ impl<'ra> DeclData<'ra> { self.res().macro_kinds() } - fn reexport_chain(self: Decl<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> { + fn reexport_chain(self: Decl<'ra>) -> SmallVec<[Reexport; 2]> { let mut reexport_chain = SmallVec::new(); let mut next_binding = self; while let DeclKind::Import { source_decl, import, .. } = next_binding.kind { - reexport_chain.push(import.simplify(r)); + reexport_chain.push(import.simplify()); next_binding = source_decl; } reexport_chain @@ -1405,8 +1405,8 @@ pub struct Resolver<'ra, 'tcx> { local_macro_def_scopes: FxHashMap> = default::fx_hash_map(), ast_transform_scopes: FxHashMap> = default::fx_hash_map(), unused_macros: FxIndexMap, - /// A map from the macro to all its potentially unused arms. - unused_macro_rules: FxIndexMap>, + /// A map from the macro to all its potentially unused arms and the `LocalDefId` of the macro itself. + unused_macro_rules: FxIndexMap)>, proc_macro_stubs: FxHashSet = default::fx_hash_set(), /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: @@ -2154,8 +2154,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> &'tcx [LocalDefId] { let mut import_ids: SmallVec<[LocalDefId; 1]> = smallvec![]; while let DeclKind::Import { import, source_decl, .. } = kind { - if let Some(node_id) = import.id() { - let def_id = self.local_def_id(node_id); + if let Some(def_id) = import.def_id() { self.maybe_unused_trait_imports.insert(def_id); import_ids.push(def_id); } @@ -2291,8 +2290,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { #[inline] fn add_to_glob_map(&mut self, import: Import<'_>, name: Symbol) { - if let ImportKind::Glob { id, .. } = import.kind { - let def_id = self.local_def_id(id); + if let ImportKind::Glob { def_id, .. } = import.kind { self.glob_map.entry(def_id).or_default().insert(name); } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index de818d933c9bc..d20907f53f66a 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -339,7 +339,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn record_macro_rule_usage(&mut self, id: NodeId, rule_i: usize) { - if let Some(rules) = self.unused_macro_rules.get_mut(&id) { + if let Some((_, rules)) = self.unused_macro_rules.get_mut(&id) { rules.remove(rule_i); } } @@ -356,11 +356,10 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { self.unused_macro_rules.swap_remove(&node_id); } - for (&node_id, unused_arms) in self.unused_macro_rules.iter() { + for (&node_id, (def_id, unused_arms)) in self.unused_macro_rules.iter() { if unused_arms.is_empty() { continue; } - let def_id = self.local_def_id(node_id); let m = &self.local_macro_map[&def_id]; let SyntaxExtensionKind::MacroRules(ref m) = m.ext.kind else { continue; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7fba8863d4e08..284bbcf17d172 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1928,6 +1928,7 @@ symbols! { sinf128, size, size_of, + size_of_type_id, size_of_val, sized, sized_hierarchy, diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index b55cbc3164d96..de3e04626f823 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -375,13 +375,17 @@ pub struct EarlyBinder { impl Eq for EarlyBinder {} -/// For early binders, you should first call `instantiate` before using any visitors. +// FIXME(154045): Recommended as per https://github.com/rust-lang/rust/issues/154045, this is so sad :(( #[cfg(feature = "nightly")] -impl !TypeFoldable for ty::EarlyBinder {} +macro_rules! generate { ($( $tt:tt )*) => { $( $tt )* } } -/// For early binders, you should first call `instantiate` before using any visitors. #[cfg(feature = "nightly")] -impl !TypeVisitable for ty::EarlyBinder {} +generate!( + /// For early binders, you should first call `instantiate` before using any visitors. + impl !TypeFoldable for ty::EarlyBinder {} + /// For early binders, you should first call `instantiate` before using any visitors. + impl !TypeVisitable for ty::EarlyBinder {} +); impl EarlyBinder { pub fn bind(value: T) -> EarlyBinder { diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 50c30f4252703..19c59df0604c3 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -118,6 +118,11 @@ bitflags::bitflags! { /// Does this have any `ReErased` regions? const HAS_RE_ERASED = 1 << 21; + /// Does this have any regions of any kind? + const HAS_REGIONS = TypeFlags::HAS_FREE_REGIONS.bits() + | TypeFlags::HAS_RE_BOUND.bits() + | TypeFlags::HAS_RE_ERASED.bits(); + /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? const STILL_FURTHER_SPECIALIZABLE = TypeFlags::HAS_TY_PARAM.bits() @@ -139,7 +144,7 @@ bitflags::bitflags! { /// Does this type have any coroutines in it? const HAS_TY_CORO = 1 << 25; - /// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`? + /// Does this have a `Bound(BoundVarIndexKind::Canonical, _)`? const HAS_CANONICAL_BOUND = 1 << 26; } } @@ -192,7 +197,7 @@ impl FlagComputation { } fn add_flags(&mut self, flags: TypeFlags) { - self.flags = self.flags | flags; + self.flags |= flags; } /// indicates that `self` refers to something at binding level `binder` diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index d1a50599e8b9c..0fe68b5256691 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -55,7 +55,7 @@ use tracing::{debug, instrument}; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; -use crate::{self as ty, BoundVarIndexKind, Interner, TypeFlags}; +use crate::{self as ty, BoundVarIndexKind, Interner}; /// This trait is implemented for every type that can be folded, /// providing the skeleton of the traversal. @@ -121,10 +121,6 @@ pub trait TypeSuperFoldable: TypeFoldable { /// default that does an "identity" fold. Implementations of these methods /// often fall back to a `super_fold_with` method if the primary argument /// doesn't satisfy a particular condition. -/// -/// A blanket implementation of [`FallibleTypeFolder`] will defer to -/// the infallible methods of this trait to ensure that the two APIs -/// are coherent. pub trait TypeFolder: Sized { fn cx(&self) -> I; @@ -437,6 +433,10 @@ impl TypeFolder for Shifter { fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } } + + fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses { + if c.has_vars_bound_at_or_above(self.current_index) { c.super_fold_with(self) } else { c } + } } pub fn shift_region(cx: I, region: I::Region, amount: u32) -> I::Region { @@ -477,10 +477,10 @@ where /// Folds over the substructure of a type, visiting its component /// types and all regions that occur *free* within it. /// -/// That is, function pointer types and trait object can introduce -/// new bound regions which are not visited by this visitors as +/// That is, function pointer types and trait objects can introduce +/// new bound regions which are not visited by this visitor as /// they are not free; only regions that occur free will be -/// visited by `fld_r`. +/// visited by `fold_region_fn`. pub struct RegionFolder { cx: I, @@ -489,7 +489,7 @@ pub struct RegionFolder { /// binder, it is incremented (via `shift_in`). current_index: ty::DebruijnIndex, - /// Callback invokes for each free region. The `DebruijnIndex` + /// Callback invoked for each free region. The `DebruijnIndex` /// points to the binder *just outside* the ones we have passed /// through. fold_region_fn: F, @@ -539,32 +539,18 @@ where } fn fold_ty(&mut self, t: I::Ty) -> I::Ty { - if t.has_type_flags( - TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, - ) { - t.super_fold_with(self) - } else { - t - } + if t.has_regions() { t.super_fold_with(self) } else { t } } fn fold_const(&mut self, ct: I::Const) -> I::Const { - if ct.has_type_flags( - TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, - ) { - ct.super_fold_with(self) - } else { - ct - } + if ct.has_regions() { ct.super_fold_with(self) } else { ct } } fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { - if p.has_type_flags( - TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, - ) { - p.super_fold_with(self) - } else { - p - } + if p.has_regions() { p.super_fold_with(self) } else { p } + } + + fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses { + if c.has_regions() { c.super_fold_with(self) } else { c } } } diff --git a/compiler/rustc_type_ir/src/generic_visit.rs b/compiler/rustc_type_ir/src/generic_visit.rs index 6669168443a4a..6adaf4d158f40 100644 --- a/compiler/rustc_type_ir/src/generic_visit.rs +++ b/compiler/rustc_type_ir/src/generic_visit.rs @@ -212,6 +212,7 @@ trivial_impls!( rustc_hash::FxBuildHasher, crate::TypeFlags, crate::solve::GoalSource, + crate::solve::VisibleForLeakCheck, rustc_abi::ExternAbi, ); diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f63361f5968d2..7ff447a81a284 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -55,7 +55,11 @@ pub trait Ty>: fn new_alias(interner: I, alias_ty: ty::AliasTy) -> Self; - fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self { + fn new_projection_from_args( + interner: I, + def_id: I::TraitAssocTyId, + args: I::GenericArgs, + ) -> Self { Self::new_alias( interner, ty::AliasTy::new_from_args(interner, ty::AliasTyKind::Projection { def_id }, args), @@ -64,7 +68,7 @@ pub trait Ty>: fn new_projection( interner: I, - def_id: I::DefId, + def_id: I::TraitAssocTyId, args: impl IntoIterator>, ) -> Self { Self::new_alias( @@ -637,19 +641,24 @@ pub trait Features: Copy { } #[rust_analyzer::prefer_underscore_import] -pub trait DefId: Copy + Debug + Hash + Eq + TypeFoldable { +pub trait DefId::LocalDefId>: + Copy + Debug + Hash + Eq + TypeFoldable +{ fn is_local(self) -> bool; - fn as_local(self) -> Option; + fn as_local(self) -> Option; } -pub trait SpecificDefId: - DefId + Into + TryFrom +pub trait SpecificDefId::LocalDefId>: + DefId + Into + TryFrom { } -impl + Into + TryFrom> - SpecificDefId for T +impl< + I: Interner, + T: DefId + Into + TryFrom, + Local, +> SpecificDefId for T { } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index e13c4279a68a1..f25bc5fc4e3c9 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -9,7 +9,7 @@ use rustc_index::bit_set::DenseBitSet; use crate::fold::TypeFoldable; use crate::inherent::*; use crate::ir_print::IrPrint; -use crate::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; +use crate::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem}; use crate::relate::Relate; use crate::solve::{ AccessedOpaques, CanonicalInput, Certainty, ExternalConstraintsData, QueryResult, inspect, @@ -56,6 +56,38 @@ pub trait Interner: type AdtId: SpecificDefId; type ImplId: SpecificDefId; type UnevaluatedConstId: SpecificDefId; + type TraitAssocTyId: SpecificDefId + + Into + + TryFrom; + type TraitAssocConstId: SpecificDefId + + Into + + Into + + TryFrom; + type TraitAssocTermId: SpecificDefId; + type OpaqueTyId: SpecificDefId; + type LocalOpaqueTyId: Copy + + Debug + + Hash + + Eq + + Into + + Into + + Into + + TypeFoldable; + type FreeTyAliasId: SpecificDefId + Into; + type FreeConstAliasId: SpecificDefId + + Into + + Into; + type FreeTermAliasId: SpecificDefId; + type ImplOrTraitAssocTyId: SpecificDefId + Into; + type ImplOrTraitAssocConstId: SpecificDefId + + Into + + Into; + type ImplOrTraitAssocTermId: SpecificDefId; + type InherentAssocTyId: SpecificDefId + Into; + type InherentAssocConstId: SpecificDefId + + Into + + Into; + type InherentAssocTermId: SpecificDefId; type Span: Span; type GenericArgs: GenericArgs; @@ -203,8 +235,10 @@ pub trait Interner: ) -> Option; fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder; - fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) - -> ty::EarlyBinder; + fn type_of_opaque_hir_typeck( + self, + def_id: Self::LocalOpaqueTyId, + ) -> ty::EarlyBinder; fn is_type_const(self, def_id: Self::DefId) -> bool; fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder; fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; @@ -219,7 +253,7 @@ pub trait Interner: fn trait_ref_and_own_args_for_alias( self, - def_id: Self::DefId, + def_id: Self::TraitAssocTermId, args: Self::GenericArgs, ) -> (ty::TraitRef, Self::GenericArgsSlice); @@ -243,7 +277,12 @@ pub trait Interner: I: Iterator, T: CollectAndApply; - fn parent(self, def_id: Self::DefId) -> Self::DefId; + fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId; + + /// This can be an impl, or a trait if this is a defaulted term. + fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId; + + fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId; fn recursion_limit(self) -> usize; @@ -325,13 +364,20 @@ pub trait Interner: fn has_target_features(self, def_id: Self::FunctionId) -> bool; - fn require_lang_item(self, lang_item: SolverLangItem) -> Self::DefId; + fn require_projection_lang_item( + self, + lang_item: SolverProjectionLangItem, + ) -> Self::TraitAssocTyId; fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> Self::TraitId; fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> Self::AdtId; - fn is_lang_item(self, def_id: Self::DefId, lang_item: SolverLangItem) -> bool; + fn is_projection_lang_item( + self, + def_id: Self::TraitAssocTyId, + lang_item: SolverProjectionLangItem, + ) -> bool; fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool; @@ -341,7 +387,10 @@ pub trait Interner: fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool; - fn as_lang_item(self, def_id: Self::DefId) -> Option; + fn as_projection_lang_item( + self, + def_id: Self::TraitAssocTyId, + ) -> Option; fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option; @@ -360,7 +409,7 @@ pub trait Interner: ); fn for_each_blanket_impl(self, trait_def_id: Self::TraitId, f: impl FnMut(Self::ImplId)); - fn has_item_definition(self, def_id: Self::DefId) -> bool; + fn has_item_definition(self, def_id: Self::ImplOrTraitAssocTermId) -> bool; fn impl_specializes(self, impl_def_id: Self::ImplId, victim_def_id: Self::ImplId) -> bool; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 5af2bd811bab4..c6ab804d81c9f 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,11 +1,12 @@ use std::fmt; use crate::{ - AliasTerm, AliasTy, Binder, ClosureKind, CoercePredicate, ExistentialProjection, - ExistentialTraitRef, FnSig, HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, - PatternKind, Placeholder, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, - UnevaluatedConst, + AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig, + HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, PatternKind, Placeholder, + ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, }; +#[cfg(feature = "nightly")] +use crate::{ClosureKind, UnevaluatedConst}; pub trait IrPrint { fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index f1c45a4d98b5e..4ed574a55ece1 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -1,6 +1,6 @@ /// Lang items used by the new trait solver. This can be mapped to whatever internal /// representation of `LangItem`s used in the underlying compiler implementation. -pub enum SolverLangItem { +pub enum SolverProjectionLangItem { // tidy-alphabetical-start AsyncFnKindUpvars, AsyncFnOnceOutput, @@ -8,7 +8,6 @@ pub enum SolverLangItem { CallRefFuture, CoroutineReturn, CoroutineYield, - DynMetadata, FieldBase, FieldType, FutureOutput, @@ -18,6 +17,7 @@ pub enum SolverLangItem { pub enum SolverAdtLangItem { // tidy-alphabetical-start + DynMetadata, Option, Poll, // tidy-alphabetical-end @@ -29,7 +29,6 @@ pub enum SolverTraitLangItem { AsyncFnKindHelper, AsyncFnMut, AsyncFnOnce, - AsyncFnOnceOutput, AsyncIterator, BikeshedGuaranteedNoDrop, Clone, diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index 782a7d30b675b..d050cc2fe05aa 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -13,7 +13,7 @@ use crate::{self as ty, Interner}; derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) )] pub struct OpaqueTypeKey { - pub def_id: I::LocalDefId, + pub def_id: I::LocalOpaqueTyId, pub args: I::GenericArgs, } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 7b815e61cf09e..301cf7dbf1087 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -472,7 +472,7 @@ impl ty::Binder> { derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) )] pub struct ExistentialProjection { - pub def_id: I::DefId, + pub def_id: I::TraitAssocTermId, pub args: I::GenericArgs, pub term: I::Term, @@ -487,17 +487,17 @@ impl Eq for ExistentialProjection {} impl ExistentialProjection { pub fn new_from_args( interner: I, - def_id: I::DefId, + def_id: I::TraitAssocTermId, args: I::GenericArgs, term: I::Term, ) -> ExistentialProjection { - interner.debug_assert_existential_args_compatible(def_id, args); + interner.debug_assert_existential_args_compatible(def_id.into(), args); Self { def_id, args, term, use_existential_projection_new_instead: () } } pub fn new( interner: I, - def_id: I::DefId, + def_id: I::TraitAssocTermId, args: impl IntoIterator>, term: I::Term, ) -> ExistentialProjection { @@ -511,10 +511,10 @@ impl ExistentialProjection { /// then this function would return an `exists T. T: Iterator` existential trait /// reference. pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef { - let def_id = interner.parent(self.def_id); - let args_count = interner.generics_of(def_id).count() - 1; + let def_id = interner.projection_parent(self.def_id); + let args_count = interner.generics_of(def_id.into()).count() - 1; let args = interner.mk_args(&self.args.as_slice()[..args_count]); - ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args) + ExistentialTraitRef::new_from_args(interner, def_id, args) } pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate { @@ -524,7 +524,7 @@ impl ExistentialProjection { ProjectionPredicate { projection_term: AliasTerm::new( interner, - interner.alias_term_kind_from_def_id(self.def_id), + interner.alias_term_kind_from_def_id(self.def_id.into()), [self_ty.into()].iter().chain(self.args.iter()), ), term: self.term, @@ -536,7 +536,7 @@ impl ExistentialProjection { projection_predicate.projection_term.args.type_at(0); Self { - def_id: projection_predicate.projection_term.def_id(), + def_id: projection_predicate.def_id(), args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]), term: projection_predicate.term, use_existential_projection_new_instead: (), @@ -549,13 +549,13 @@ impl ty::Binder> { self.map_bound(|p| p.with_self_ty(cx, self_ty)) } - pub fn item_def_id(&self) -> I::DefId { + pub fn item_def_id(&self) -> I::TraitAssocTermId { self.skip_binder().def_id } } #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] -#[derive(Lift_Generic)] +#[derive(Lift_Generic, GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) @@ -570,12 +570,12 @@ pub enum AliasTermKind { /// Note that the `def_id` is not the `DefId` of the `TraitRef` containing this /// associated type, which is in `interner.associated_item(def_id).container`, /// aka. `interner.parent(def_id)`. - ProjectionTy { def_id: I::DefId }, + ProjectionTy { def_id: I::TraitAssocTyId }, /// An associated type in an inherent `impl` /// /// The `def_id` is the `DefId` of the `ImplItem` for the associated type. - InherentTy { def_id: I::DefId }, + InherentTy { def_id: I::InherentAssocTyId }, /// An opaque type (usually from `impl Trait` in type aliases or function return types) /// @@ -585,22 +585,22 @@ pub enum AliasTermKind { /// /// During codegen, `interner.type_of(def_id)` can be used to get the type of the /// underlying type if the type is an opaque. - OpaqueTy { def_id: I::DefId }, + OpaqueTy { def_id: I::OpaqueTyId }, /// A type alias that actually checks its trait bounds. /// /// Currently only used if the type alias references opaque types. /// Can always be normalized away. - FreeTy { def_id: I::DefId }, + FreeTy { def_id: I::FreeTyAliasId }, /// An unevaluated anonymous constants. - UnevaluatedConst { def_id: I::DefId }, + UnevaluatedConst { def_id: I::UnevaluatedConstId }, /// An unevaluated const coming from an associated const. - ProjectionConst { def_id: I::DefId }, + ProjectionConst { def_id: I::TraitAssocConstId }, /// A top level const item not part of a trait or impl. - FreeConst { def_id: I::DefId }, + FreeConst { def_id: I::FreeConstAliasId }, /// An associated const in an inherent `impl` - InherentConst { def_id: I::DefId }, + InherentConst { def_id: I::InherentAssocConstId }, } impl AliasTermKind { @@ -631,17 +631,18 @@ impl AliasTermKind { } } - // FIXME: replace with explicit matches + // FIXME(#156181): replace with explicit matches pub fn def_id(self) -> I::DefId { - let (AliasTermKind::ProjectionTy { def_id } - | AliasTermKind::InherentTy { def_id } - | AliasTermKind::OpaqueTy { def_id } - | AliasTermKind::FreeTy { def_id } - | AliasTermKind::UnevaluatedConst { def_id } - | AliasTermKind::ProjectionConst { def_id } - | AliasTermKind::FreeConst { def_id } - | AliasTermKind::InherentConst { def_id }) = self; - def_id + match self { + AliasTermKind::ProjectionTy { def_id } => def_id.into(), + AliasTermKind::InherentTy { def_id } => def_id.into(), + AliasTermKind::OpaqueTy { def_id } => def_id.into(), + AliasTermKind::FreeTy { def_id } => def_id.into(), + AliasTermKind::UnevaluatedConst { def_id } => def_id.into(), + AliasTermKind::ProjectionConst { def_id } => def_id.into(), + AliasTermKind::FreeConst { def_id } => def_id.into(), + AliasTermKind::InherentConst { def_id } => def_id.into(), + } } } @@ -737,11 +738,11 @@ impl AliasTerm { } pub fn expect_ct(self, interner: I) -> ty::UnevaluatedConst { - let def_id = match self.kind(interner) { - AliasTermKind::InherentConst { def_id } - | AliasTermKind::FreeConst { def_id } - | AliasTermKind::UnevaluatedConst { def_id } - | AliasTermKind::ProjectionConst { def_id } => def_id, + let def = match self.kind(interner) { + AliasTermKind::InherentConst { def_id } => def_id.into(), + AliasTermKind::FreeConst { def_id } => def_id.into(), + AliasTermKind::UnevaluatedConst { def_id } => def_id, + AliasTermKind::ProjectionConst { def_id } => def_id.into(), kind @ (AliasTermKind::ProjectionTy { .. } | AliasTermKind::InherentTy { .. } | AliasTermKind::OpaqueTy { .. } @@ -749,7 +750,7 @@ impl AliasTerm { panic!("Cannot turn `{}` into `UnevaluatedConst`", kind.descr()) } }; - ty::UnevaluatedConst { def: def_id.try_into().unwrap(), args: self.args } + ty::UnevaluatedConst { def, args: self.args } } // FIXME: remove this function (access the field instead) @@ -763,17 +764,14 @@ impl AliasTerm { } pub fn to_term(self, interner: I) -> I::Term { + let unevaluated_const = |def_id| { + I::Const::new_unevaluated(interner, ty::UnevaluatedConst::new(def_id, self.args)).into() + }; let alias_ty_kind = match self.kind(interner) { - AliasTermKind::FreeConst { def_id } - | AliasTermKind::InherentConst { def_id } - | AliasTermKind::UnevaluatedConst { def_id } - | AliasTermKind::ProjectionConst { def_id } => { - return I::Const::new_unevaluated( - interner, - ty::UnevaluatedConst::new(def_id.try_into().unwrap(), self.args), - ) - .into(); - } + AliasTermKind::FreeConst { def_id } => return unevaluated_const(def_id.into()), + AliasTermKind::InherentConst { def_id } => return unevaluated_const(def_id.into()), + AliasTermKind::UnevaluatedConst { def_id } => return unevaluated_const(def_id), + AliasTermKind::ProjectionConst { def_id } => return unevaluated_const(def_id.into()), AliasTermKind::ProjectionTy { def_id } => ty::Projection { def_id }, AliasTermKind::InherentTy { def_id } => ty::Inherent { def_id }, @@ -804,15 +802,25 @@ impl AliasTerm { ) } + fn projection_def_id(self) -> Option { + match self.kind { + AliasTermKind::ProjectionTy { def_id } => Some(def_id.into()), + AliasTermKind::ProjectionConst { def_id } => Some(def_id.into()), + AliasTermKind::InherentTy { .. } + | AliasTermKind::OpaqueTy { .. } + | AliasTermKind::FreeTy { .. } + | AliasTermKind::UnevaluatedConst { .. } + | AliasTermKind::FreeConst { .. } + | AliasTermKind::InherentConst { .. } => None, + } + } + + fn expect_projection_def_id(self) -> I::TraitAssocTermId { + self.projection_def_id().expect("expected a projection") + } + pub fn trait_def_id(self, interner: I) -> I::TraitId { - assert!( - matches!( - self.kind(interner), - AliasTermKind::ProjectionTy { .. } | AliasTermKind::ProjectionConst { .. } - ), - "expected a projection" - ); - interner.parent(self.def_id()).try_into().unwrap() + interner.projection_parent(self.expect_projection_def_id()) } /// Extracts the underlying trait reference and own args from this projection. @@ -820,7 +828,7 @@ impl AliasTerm { /// then this function would return a `T: StreamingIterator` trait reference and /// `['a]` as the own args. pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef, I::GenericArgsSlice) { - interner.trait_ref_and_own_args_for_alias(self.def_id(), self.args) + interner.trait_ref_and_own_args_for_alias(self.expect_projection_def_id(), self.args) } /// Extracts the underlying trait reference from this projection. @@ -918,8 +926,8 @@ impl ProjectionPredicate { self.projection_term.trait_def_id(interner) } - pub fn def_id(self) -> I::DefId { - self.projection_term.def_id() + pub fn def_id(self) -> I::TraitAssocTermId { + self.projection_term.expect_projection_def_id() } } diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 425436dabafb2..51de99e92fcad 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -268,7 +268,10 @@ impl Relate for ty::ExistentialProjection { b: ty::ExistentialProjection, ) -> RelateResult> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.def_id, b.def_id))) + Err(TypeError::ProjectionMismatched(ExpectedFound::new( + a.def_id.into(), + b.def_id.into(), + ))) } else { let term = relation.relate_with_variance( ty::Invariant, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 0634c9b741d38..cf9530378dc7c 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -535,7 +535,7 @@ pub enum BuiltinImplSource { #[derive_where(Copy, Clone, Debug; I: Interner)] pub enum FetchEligibleAssocItemResponse { Err(I::ErrorGuaranteed), - Found(I::DefId), + Found(I::ImplOrTraitAssocTermId), NotFound(TypingMode), NotFoundBecauseErased, } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index a08bd00eeed65..0fc39660015de 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -39,12 +39,12 @@ pub enum AliasTyKind { /// Note that the `def_id` is not the `DefId` of the `TraitRef` containing this /// associated type, which is in `interner.associated_item(def_id).container`, /// aka. `interner.parent(def_id)`. - Projection { def_id: I::DefId }, + Projection { def_id: I::TraitAssocTyId }, /// An associated type in an inherent `impl` /// /// The `def_id` is the `DefId` of the `ImplItem` for the associated type. - Inherent { def_id: I::DefId }, + Inherent { def_id: I::InherentAssocTyId }, /// An opaque type (usually from `impl Trait` in type aliases or function return types) /// @@ -55,13 +55,13 @@ pub enum AliasTyKind { /// /// During codegen, `interner.type_of(def_id)` can be used to get the type of the /// underlying type if the type is an opaque. - Opaque { def_id: I::DefId }, + Opaque { def_id: I::OpaqueTyId }, /// A type alias that actually checks its trait bounds. /// /// Currently only used if the type alias references opaque types. /// Can always be normalized away. - Free { def_id: I::DefId }, + Free { def_id: I::FreeTyAliasId }, } impl AliasTyKind { @@ -79,12 +79,12 @@ impl AliasTyKind { } pub fn def_id(self) -> I::DefId { - let (AliasTyKind::Projection { def_id } - | AliasTyKind::Inherent { def_id } - | AliasTyKind::Opaque { def_id } - | AliasTyKind::Free { def_id }) = self; - - def_id + match self { + AliasTyKind::Projection { def_id } => def_id.into(), + AliasTyKind::Inherent { def_id } => def_id.into(), + AliasTyKind::Opaque { def_id } => def_id.into(), + AliasTyKind::Free { def_id } => def_id.into(), + } } } @@ -506,10 +506,10 @@ impl AliasTy { ) } - pub fn trait_def_id(self, interner: I) -> I::DefId { + pub fn trait_def_id(self, interner: I) -> I::TraitId { let AliasTyKind::Projection { def_id } = self.kind else { panic!("expected a projection") }; - interner.parent(def_id) + interner.projection_parent(def_id.into()) } /// Extracts the underlying trait reference and own args from this projection. @@ -520,7 +520,7 @@ impl AliasTy { pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef, I::GenericArgsSlice) { let AliasTyKind::Projection { def_id } = self.kind else { panic!("expected a projection") }; - interner.trait_ref_and_own_args_for_alias(def_id, self.args) + interner.trait_ref_and_own_args_for_alias(def_id.into(), self.args) } /// Extracts the underlying trait reference from this projection. diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index a078b860be774..492c37481298b 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -67,7 +67,7 @@ pub trait TypeVisitable: fmt::Debug { /// each field/element. /// /// For types of interest (such as `Ty`), the implementation of this method - /// that calls a visitor method specifically for that type (such as + /// calls a visitor method specifically for that type (such as /// `V::visit_ty`). This is where control transfers from `TypeVisitable` to /// `TypeVisitor`. fn visit_with>(&self, visitor: &mut V) -> V::Result; @@ -102,8 +102,8 @@ pub trait TypeVisitor: Sized { t.super_visit_with(self) } - // The default region visitor is a no-op because `Region` is non-recursive - // and has no `super_visit_with` method to call. + // `Region` is non-recursive so the default region visitor has no + // `super_visit_with` method to call. fn visit_region(&mut self, r: I::Region) -> Self::Result { if let ty::ReError(guar) = r.kind() { self.visit_error(guar) @@ -251,10 +251,10 @@ pub trait TypeVisitableExt: TypeVisitable { self.has_vars_bound_at_or_above(binder.shifted_in(1)) } - /// Return `true` if this type has regions that are not a part of the type. - /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` - /// would return `true`. The latter can occur when traversing through the - /// former. + /// Returns `true` if this type has regions that are not a part of the + /// type. For example, given a `for<'a> fn(&'a i32)` this function returns + /// `false`, while given a `fn(&'a i32)` it returns `true`. The latter can + /// occur when traversing through the former. /// /// See [`HasEscapingVarsVisitor`] for more information. fn has_escaping_bound_vars(&self) -> bool { @@ -285,6 +285,10 @@ pub trait TypeVisitableExt: TypeVisitable { self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM) } + fn has_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_REGIONS) + } + fn has_infer_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_RE_INFER) } @@ -363,13 +367,12 @@ pub trait TypeVisitableExt: TypeVisitable { impl> TypeVisitableExt for T { fn has_type_flags(&self, flags: TypeFlags) -> bool { - let res = - self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags); - res + self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags) } fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { - self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break() + self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }) + == ControlFlow::Break(FoundEscapingVars) } fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { @@ -438,8 +441,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { #[inline] fn visit_ty(&mut self, t: I::Ty) -> Self::Result { // Note: no `super_visit_with` call. - let flags = t.flags(); - if flags.intersects(self.flags) { + if t.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { ControlFlow::Continue(()) @@ -449,8 +451,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { #[inline] fn visit_region(&mut self, r: I::Region) -> Self::Result { // Note: no `super_visit_with` call, as usual for `Region`. - let flags = r.flags(); - if flags.intersects(self.flags) { + if r.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { ControlFlow::Continue(()) @@ -571,7 +572,7 @@ impl TypeVisitor for HasEscapingVarsVisitor { // `outer_index`, that means that `ct` contains some content // bound at `outer_index` or above (because // `outer_exclusive_binder` is always 1 higher than the - // content in `t`). Therefore, `t` has some escaping vars. + // content in `ct`). Therefore, `ct` has some escaping vars. if ct.outer_exclusive_binder() > self.outer_index { ControlFlow::Break(FoundEscapingVars) } else { diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 7d820403ccb7d..62300d8b70a96 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -839,7 +839,7 @@ impl TypeId { self, trait_represented_by_type_id: TypeId, ) -> Option> { - if self.info().size.is_none() { + if self.size().is_none() { return None; } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c71085ef9f97d..8eaf91dab8dfb 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2937,6 +2937,15 @@ pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool { a.data == b.data } +/// Gets the size of the type represented by this `TypeId`. +/// +/// The stabilized version of this intrinsic is [`core::any::TypeId::size`]. +#[rustc_intrinsic] +#[unstable(feature = "core_intrinsics", issue = "none")] +pub const fn size_of_type_id(_id: crate::any::TypeId) -> Option { + panic!("`Type::size` can only be called at compile-time") +} + /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`. /// /// This is used to implement functions like `slice::from_raw_parts_mut` and diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index e4d47dedb8606..17c51ccaad858 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -2,7 +2,7 @@ //! runtime or const-eval processable way. use crate::any::TypeId; -use crate::intrinsics::{type_id, type_of}; +use crate::intrinsics::{self, type_id, type_of}; use crate::marker::PointeeSized; use crate::ptr::DynMetadata; @@ -14,8 +14,6 @@ use crate::ptr::DynMetadata; pub struct Type { /// Per-type information pub kind: TypeKind, - /// Size of the type. `None` if it is unsized - pub size: Option, } /// Info of a trait implementation, you can retrieve the vtable with [Self::get_vtable] @@ -360,3 +358,22 @@ pub enum Abi { /// C-calling convention ExternC, } + +impl TypeId { + /// Returns the size of the type represented by this `TypeId`. `None` if it is unsized. + /// + /// # Examples + /// + /// ``` + /// #![feature(type_info)] + /// use std::any::TypeId; + /// + /// assert_eq!(const { TypeId::of::().size() }, Some(4)); + /// assert_eq!(const { TypeId::of::<[u8; 16]>().size() }, Some(16)); + /// ``` + #[unstable(feature = "type_info", issue = "146922")] + #[rustc_const_unstable(feature = "type_info", issue = "146922")] + pub const fn size(self) -> Option { + intrinsics::size_of_type_id(self) + } +} diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 2483b4c2aacd7..e02077b96d35a 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -80,8 +80,7 @@ fn test_structs() { reference: &'static u16, } - let Type { kind: Struct(ty), size, .. } = Type::of::() else { panic!() }; - assert!(size == Some(size_of::())); + let Type { kind: Struct(ty), .. } = Type::of::() else { panic!() }; assert!(!ty.non_exhaustive); assert!(ty.fields.len() == 3); assert!(ty.fields[0].name == "first"); @@ -93,6 +92,9 @@ fn test_structs() { assert!(ty.fields[2].name == "reference"); assert!(ty.fields[2].ty == TypeId::of::<&'static u16>()); assert!(ty.fields[2].offset == offset_of!(TestStruct, reference)); + + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); } const { @@ -145,13 +147,15 @@ fn test_unions() { second: u16, } - let Type { kind: Union(ty), size, .. } = Type::of::() else { panic!() }; - assert!(size == Some(size_of::())); + let Type { kind: Union(ty), .. } = Type::of::() else { panic!() }; assert!(ty.fields.len() == 2); assert!(ty.fields[0].name == "first"); assert!(ty.fields[0].offset == offset_of!(TestUnion, first)); assert!(ty.fields[1].name == "second"); assert!(ty.fields[1].offset == offset_of!(TestUnion, second)); + + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); } const { @@ -191,8 +195,7 @@ fn test_enums() { }, } - let Type { kind: Enum(ty), size, .. } = Type::of::() else { panic!() }; - assert!(size == Some(size_of::())); + let Type { kind: Enum(ty), .. } = Type::of::() else { panic!() }; assert!(ty.variants.len() == 3); assert!(ty.variants[0].name == "Some"); @@ -206,15 +209,20 @@ fn test_enums() { assert!(ty.variants[2].name == "Foomp"); assert!(ty.variants[2].non_exhaustive); assert!(ty.variants[2].fields.len() == 2); + + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); } const { - let Type { kind: Enum(ty), size, .. } = Type::of::>() else { panic!() }; - assert!(size == Some(size_of::>())); + let Type { kind: Enum(ty), .. } = Type::of::>() else { panic!() }; assert!(ty.variants.len() == 2); assert!(ty.generics.len() == 1); let Generic::Type(GenericType { ty: generic_ty, .. }) = ty.generics[0] else { panic!() }; assert!(generic_ty == TypeId::of::()); + + let ty_id = TypeId::of::>(); + assert!(ty_id.size() == Some(size_of::>())); } } @@ -222,38 +230,48 @@ fn test_enums() { fn test_primitives() { use TypeKind::*; - let Type { kind: Bool(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(1)); - - let Type { kind: Char(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(4)); - - let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(4)); - assert_eq!(ty.bits, 32); - assert!(ty.signed); - - let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(size_of::())); - assert_eq!(ty.bits as usize, size_of::() * 8); - assert!(ty.signed); - - let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(4)); - assert_eq!(ty.bits, 32); - assert!(!ty.signed); - - let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(size_of::())); - assert_eq!(ty.bits as usize, size_of::() * 8); - assert!(!ty.signed); - - let Type { kind: Float(ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, Some(4)); - assert_eq!(ty.bits, 32); - - let Type { kind: Str(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; - assert_eq!(size, None); + const { + let Type { kind: Bool(_ty), .. } = (const { Type::of::() }) else { panic!() }; + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Char(_ty), .. } = (const { Type::of::() }) else { panic!() }; + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Int(ty), .. } = (const { Type::of::() }) else { panic!() }; + assert!(ty.bits == 32); + assert!(ty.signed); + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Int(ty), .. } = (const { Type::of::() }) else { panic!() }; + assert!(ty.bits as usize == size_of::() * 8); + assert!(ty.signed); + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Int(ty), .. } = (const { Type::of::() }) else { panic!() }; + assert!(ty.bits == 32); + assert!(!ty.signed); + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Int(ty), .. } = (const { Type::of::() }) else { panic!() }; + assert!(ty.bits as usize == size_of::() * 8); + assert!(!ty.signed); + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Float(ty), .. } = (const { Type::of::() }) else { panic!() }; + assert!(ty.bits == 32); + let ty_id = TypeId::of::(); + assert!(ty_id.size() == Some(size_of::())); + + let Type { kind: Str(_ty), .. } = (const { Type::of::() }) else { panic!() }; + let ty_id = TypeId::of::(); + assert!(ty_id.size() == None); + } } #[test] diff --git a/library/std/src/sys/io/error/mod.rs b/library/std/src/sys/io/error/mod.rs index 4fca658a7dcaa..cc8cda9aec045 100644 --- a/library/std/src/sys/io/error/mod.rs +++ b/library/std/src/sys/io/error/mod.rs @@ -43,6 +43,7 @@ cfg_select! { target_os = "vexos", target_family = "wasm", target_os = "zkvm", + target_os = "trusty", ) => { mod generic; pub use generic::*; diff --git a/library/std/src/sys/time/windows.rs b/library/std/src/sys/time/windows.rs index 2e38dbf5cf288..b2abee4219fe3 100644 --- a/library/std/src/sys/time/windows.rs +++ b/library/std/src/sys/time/windows.rs @@ -35,7 +35,14 @@ impl Instant { let freq = perf_counter::frequency() as u64; let now = perf_counter::now(); + + // We convert now to `u64` to be able to use `Duration`. let instant_nsec = mul_div_u64(now as u64, NANOS_PER_SEC, freq); + // We can add an arbitrary offset to shift the epoch of this clock. We do that to avoid + // being too close to 0 which would lead to underflow when computing times in the past. Also + // see . + let instant_nsec = instant_nsec + (u64::MAX / 4); + Self { t: Duration::from_nanos(instant_nsec) } } diff --git a/library/std/tests/time.rs b/library/std/tests/time.rs index b73e7bc3962eb..d6736e25ace18 100644 --- a/library/std/tests/time.rs +++ b/library/std/tests/time.rs @@ -1,4 +1,5 @@ #![feature(duration_constants)] +#![feature(duration_constructors)] #![feature(time_systemtime_limits)] #![feature(time_saturating_systemtime)] @@ -104,7 +105,8 @@ fn instant_math_is_associative() { #[test] fn instant_duration_since_saturates() { let a = Instant::now(); - assert_eq!((a - Duration::SECOND).duration_since(a), Duration::ZERO); + // This also checks that computing an instant before program startup works. + assert_eq!((a - Duration::from_days(1)).duration_since(a), Duration::ZERO); } #[test] diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index eb74edda22de8..16499659291a0 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -70,17 +70,16 @@ be used instead. [`wasi-libc`]: https://github.com/WebAssembly/wasi-libc -## Building the target +## Building the target in rustc -To build this target first acquire a copy of -[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22 -is the minimum needed. +To build this target first acquire a copy of [`wasi-sdk`]. At this time version +33 is the minimum needed. Next configure the `WASI_SDK_PATH` environment variable to point to where this is installed. For example: ```text -export WASI_SDK_PATH=/path/to/wasi-sdk-22.0 +export WASI_SDK_PATH=/path/to/wasi-sdk-33.0 ``` Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld` @@ -103,6 +102,16 @@ Rust programs can be built for that target: rustc --target wasm32-wasip1 your-code.rs ``` +The `wasm32-wasip1` toolchain comes with a self-contained sysroot meaning that +no external compiler is required when building for this target. Users which +build a `staticlib`, however, or use an external `-Clinker`, are recommended to +use [`wasi-sdk`]. The minimum version required of [`wasi-sdk`] will change over +time as it's updated in Rust and Rust relies on newer features that [`wasi-sdk`] +has. See the documentation above about building the target in rustc for the +minimum known working version. + +[`wasi-sdk`]: https://github.com/WebAssembly/wasi-sdk + ## Cross-compilation This target can be cross-compiled from any hosts. diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index 861083ad4a61a..4b7e84d715769 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -27,23 +27,20 @@ are required to support components since this target outputs a component as opposed to a core wasm module. As of the time of this writing Wasmtime 17 and above is able to run this target natively with no extra flags. -## Building the target +## Building the target in rustc -To build this target first acquire a copy of -[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22 -is the minimum needed. +See the documentation for the [building the `wasm32-wasip1` target in +rustc](./wasm32-wasip1.md#building-the-target-in-rustc) for more information. The tl;dr; +is that [`wasi-sdk`] is required, and the `wasm32-wasip1` target documents the +minimum version required. -Next configure the `WASI_SDK_PATH` environment variable to point to where this -is installed. For example: +[`wasi-sdk`]: https://github.com/WebAssembly/wasi-sdk -```text -export WASI_SDK_PATH=/path/to/wasi-sdk-22.0 -``` +## Building Rust programs -Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld` -driver for LLD is required when linking WebAssembly code together. Rust's build -system will automatically pick up any necessary binaries and programs from -`WASI_SDK_PATH`. +For more information see the documentation [`wasm32-wasip1` +target](./wasm32-wasip1.md#building-rust-programs). Replace `wasm32-wasip1` +target strings with `wasm32-wasip2`, however. ## Testing diff --git a/src/tools/compiletest/src/directives/line.rs b/src/tools/compiletest/src/directives/line.rs index 9cc24c98a859d..87e803921a853 100644 --- a/src/tools/compiletest/src/directives/line.rs +++ b/src/tools/compiletest/src/directives/line.rs @@ -30,6 +30,20 @@ pub(crate) fn line_directive<'a>( revision = Some(line_revision); raw_directive = after_close_bracket.trim_start(); + + if line_revision.contains(",") { + let suggestion: Vec<_> = line_revision + .split(",") + .map(|revision| { + format!("{COMPILETEST_DIRECTIVE_PREFIX} [{revision}]: {raw_directive}") + }) + .collect(); + panic!( + "malformed condition directive: multiple revisions aren't supported yet in `{}`, split them like\n{}", + original_line, + suggestion.join("\n"), + ); + } } else { revision = None; raw_directive = after_comment; diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 56d52982a8211..c2d73f95c5446 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -632,6 +632,21 @@ fn test_miropt_mode_forbidden_revisions() { parse_early_props(&config, "//@ revisions: CHECK"); } +#[test] +#[should_panic(expected = "malformed condition directive: multiple revisions aren't supported yet")] +fn test_multiple_revisions_in_directive() { + let directive = "//@ [foo,bar] compile-flags: -Z hello"; + + // The problem: this is seen as a single revision. + let line_directive = line_directive(Utf8Path::new("foo.txt"), LineNumber::ZERO, directive); + assert!(line_directive.is_some()); + assert_eq!(Some("foo,bar"), line_directive.unwrap().revision); + + // The solution for now: forbid directives from having multiple revisions. + let config: Config = cfg().build(); + parse_early_props(&config, directive); +} + #[test] fn test_forbidden_revisions_allowed_in_non_filecheck_dir() { let revisions = ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"]; diff --git a/tests/run-make-cargo/rustc-crates-on-stable/rmake.rs b/tests/run-make-cargo/rustc-crates-on-stable/rmake.rs index cbc1f24b8c16e..de29abfd7c3a2 100644 --- a/tests/run-make-cargo/rustc-crates-on-stable/rmake.rs +++ b/tests/run-make-cargo/rustc-crates-on-stable/rmake.rs @@ -10,7 +10,7 @@ fn main() { .env("RUSTC_STAGE", "0") .env("RUSTC", rustc_path()) // We want to disallow all nightly features to simulate a stable build - .env("RUSTFLAGS", "-Zallow-features=") + .env("RUSTFLAGS", "-D warnings -Zallow-features=") .arg("build") .arg("--manifest-path") .arg(source_root().join("Cargo.toml")) diff --git a/tests/ui/issues/issue-18539.rs b/tests/ui/coercion/coerce-bare-fn-returning-zst-to-closure.rs similarity index 77% rename from tests/ui/issues/issue-18539.rs rename to tests/ui/coercion/coerce-bare-fn-returning-zst-to-closure.rs index 66f0dabb73a25..39d4fa8457147 100644 --- a/tests/ui/issues/issue-18539.rs +++ b/tests/ui/coercion/coerce-bare-fn-returning-zst-to-closure.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18539 + //@ run-pass // Test that coercing bare fn's that return a zero sized type to // a closure doesn't cause an LLVM ERROR diff --git a/tests/ui/issues/issue-47722.rs b/tests/ui/coercion/coerce-mut-ref-to-raw-ptr-borrow-expires.rs similarity index 83% rename from tests/ui/issues/issue-47722.rs rename to tests/ui/coercion/coerce-mut-ref-to-raw-ptr-borrow-expires.rs index da08b8addda90..c9089b970c834 100644 --- a/tests/ui/issues/issue-47722.rs +++ b/tests/ui/coercion/coerce-mut-ref-to-raw-ptr-borrow-expires.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/47722 + //@ check-pass // Tests that automatic coercions from &mut T to *mut T diff --git a/tests/ui/issues/issue-33387.rs b/tests/ui/coercion/coerce-trait-object-removes-send-bound.rs similarity index 89% rename from tests/ui/issues/issue-33387.rs rename to tests/ui/coercion/coerce-trait-object-removes-send-bound.rs index 5d323612e411c..e7186d045a156 100644 --- a/tests/ui/issues/issue-33387.rs +++ b/tests/ui/coercion/coerce-trait-object-removes-send-bound.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/33387 + //@ run-pass #![feature(rustc_attrs)] diff --git a/tests/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/tests/ui/coercion/variance-coerce-unsized-cycle.rs similarity index 87% rename from tests/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs rename to tests/ui/coercion/variance-coerce-unsized-cycle.rs index 2a2b88410959c..91e16edd645b6 100644 --- a/tests/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs +++ b/tests/ui/coercion/variance-coerce-unsized-cycle.rs @@ -1,6 +1,6 @@ //@ check-pass #![allow(dead_code)] -// Regression test for #41936. The coerce-unsized trait check in +// Regression test for https://github.com/rust-lang/rust/issues/41936. The coerce-unsized trait check in // coherence was using subtyping, which triggered variance // computation, which failed because it required type info for fields // that had not (yet) been computed. diff --git a/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr index 700083069cb05..c9c15e2d62c9f 100644 --- a/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr +++ b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr @@ -6,7 +6,7 @@ note: inside `TypeId::trait_info_of::` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL -note: inside `type_info::::info` +note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>` diff --git a/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr index 700083069cb05..c9c15e2d62c9f 100644 --- a/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr +++ b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr @@ -6,7 +6,7 @@ note: inside `TypeId::trait_info_of::` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL -note: inside `type_info::::info` +note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>` diff --git a/tests/ui/reflection/trait_info_of_too_big.stderr b/tests/ui/reflection/trait_info_of_too_big.stderr index fa41d3c9ec90e..b5dc1d3cdb44a 100644 --- a/tests/ui/reflection/trait_info_of_too_big.stderr +++ b/tests/ui/reflection/trait_info_of_too_big.stderr @@ -6,7 +6,7 @@ LL | TypeId::of::<[u8; usize::MAX]>().trait_info_of_trait_type_id(TypeId::of | note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL -note: inside `type_info::::info` +note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture @@ -19,7 +19,7 @@ note: inside `TypeId::trait_info_of::` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL -note: inside `type_info::::info` +note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL error: aborting due to 2 previous errors