diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_ty_utils | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_ty_utils')
-rw-r--r-- | compiler/rustc_ty_utils/Cargo.toml | 1 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/messages.ftl | 62 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 40 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/common_traits.rs | 11 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/consts.rs | 77 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/errors.rs | 24 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/implied_bounds.rs | 18 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 149 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/layout_sanity_check.rs | 96 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/lib.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/needs_drop.rs | 9 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/opaque_types.rs | 198 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/representability.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/structural_match.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/ty.rs | 10 |
17 files changed, 491 insertions, 231 deletions
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 52fbd3ae0..51885c9b4 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -9,6 +9,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index 15a14112f..c416aa52a 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -1,57 +1,65 @@ -ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop +ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants -ty_utils_generic_constant_too_complex = overly complex generic constant - .help = consider moving this anonymous constant into a `const` function - .maybe_supported = this operation may be supported in the future +ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants -ty_utils_borrow_not_supported = borrowing is not supported in generic constants +ty_utils_array_not_supported = array construction is not supported in generic constants -ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants +ty_utils_assign_not_supported = assignment is not supported in generic constants -ty_utils_array_not_supported = array construction is not supported in generic constants +ty_utils_binary_not_supported = unsupported binary operation in generic constants ty_utils_block_not_supported = blocks are not supported in generic constants -ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants - -ty_utils_tuple_not_supported = tuple construction is not supported in generic constants +ty_utils_borrow_not_supported = borrowing is not supported in generic constants -ty_utils_index_not_supported = indexing is not supported in generic constants +ty_utils_box_not_supported = allocations are not allowed in generic constants -ty_utils_field_not_supported = field access is not supported in generic constants +ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants ty_utils_const_block_not_supported = const blocks are not supported in generic constants -ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants +ty_utils_control_flow_not_supported = control flow is not supported in generic constants -ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants +ty_utils_field_not_supported = field access is not supported in generic constants -ty_utils_yield_not_supported = generator control flow is not allowed in generic constants +ty_utils_generic_constant_too_complex = overly complex generic constant + .help = consider moving this anonymous constant into a `const` function + .maybe_supported = this operation may be supported in the future -ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants +ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope + .label = generic argument `{$arg}` used twice + .note = for this opaque type -ty_utils_box_not_supported = allocations are not allowed in generic constants +ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope + .label = argument `{$arg}` is not a generic parameter + .note = for this opaque type -ty_utils_binary_not_supported = unsupported binary operation in generic constants +ty_utils_index_not_supported = indexing is not supported in generic constants + +ty_utils_inline_asm_not_supported = assembly is not supported in generic constants ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow -ty_utils_assign_not_supported = assignment is not supported in generic constants +ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants -ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants +ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field -ty_utils_control_flow_not_supported = control flow is not supported in generic constants +ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop -ty_utils_inline_asm_not_supported = assembly is not supported in generic constants +ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants + +ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` ty_utils_operation_not_supported = unsupported operation in generic constants -ty_utils_unexpected_fnptr_associated_item = `FnPtr` trait with unexpected associated item +ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes} -ty_utils_zero_length_simd_type = monomorphising SIMD type `{$ty}` of zero length +ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants -ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field +ty_utils_tuple_not_supported = tuple construction is not supported in generic constants -ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes} +ty_utils_unexpected_fnptr_associated_item = `FnPtr` trait with unexpected associated item -ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` +ty_utils_yield_not_supported = generator control flow is not allowed in generic constants + +ty_utils_zero_length_simd_type = monomorphising SIMD type `{$ty}` of zero length diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 271284b2d..15c191046 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,5 +1,6 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; +use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, }; @@ -14,8 +15,8 @@ use rustc_target::spec::abi::Abi as SpecAbi; use std::iter; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; } // NOTE(eddyb) this is private to avoid using it from outside of @@ -237,6 +238,7 @@ fn adjust_for_rust_scalar<'tcx>( layout: TyAndLayout<'tcx>, offset: Size, is_return: bool, + drop_target_pointee: Option<Ty<'tcx>>, ) { // Booleans are always a noundef i1 that needs to be zero-extended. if scalar.is_bool() { @@ -250,14 +252,24 @@ fn adjust_for_rust_scalar<'tcx>( } // Only pointer types handled below. - let Scalar::Initialized { value: Pointer(_), valid_range} = scalar else { return }; + let Scalar::Initialized { value: Pointer(_), valid_range } = scalar else { return }; - if !valid_range.contains(0) { + // Set `nonnull` if the validity range excludes zero, or for the argument to `drop_in_place`, + // which must be nonnull per its documented safety requirements. + if !valid_range.contains(0) || drop_target_pointee.is_some() { attrs.set(ArgAttribute::NonNull); } if let Some(pointee) = layout.pointee_info_at(&cx, offset) { - if let Some(kind) = pointee.safe { + let kind = if let Some(kind) = pointee.safe { + Some(kind) + } else if let Some(pointee) = drop_target_pointee { + // The argument to `drop_in_place` is semantically equivalent to a mutable reference. + Some(PointerKind::MutableRef { unpin: pointee.is_unpin(cx.tcx, cx.param_env()) }) + } else { + None + }; + if let Some(kind) = kind { attrs.pointee_align = Some(pointee.align); // `Box` are not necessarily dereferenceable for the entire duration of the function as @@ -361,10 +373,18 @@ fn fn_abi_new_uncached<'tcx>( use SpecAbi::*; let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall); + let is_drop_in_place = + fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn(); + let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> { let span = tracing::debug_span!("arg_of"); let _entered = span.enter(); let is_return = arg_idx.is_none(); + let is_drop_target = is_drop_in_place && arg_idx == Some(0); + let drop_target_pointee = is_drop_target.then(|| match ty.kind() { + ty::RawPtr(ty::TypeAndMut { ty, .. }) => *ty, + _ => bug!("argument to drop_in_place is not a raw ptr: {:?}", ty), + }); let layout = cx.layout_of(ty)?; let layout = if force_thin_self_ptr && arg_idx == Some(0) { @@ -378,7 +398,15 @@ fn fn_abi_new_uncached<'tcx>( let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| { let mut attrs = ArgAttributes::new(); - adjust_for_rust_scalar(*cx, &mut attrs, scalar, *layout, offset, is_return); + adjust_for_rust_scalar( + *cx, + &mut attrs, + scalar, + *layout, + offset, + is_return, + drop_target_pointee, + ); attrs }); diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index de1e1a527..ed574f22e 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,11 +4,12 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, InternalSubsts, TyCtxt}; use rustc_span::symbol::kw; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub fn provide(providers: &mut Providers) { + *providers = Providers { associated_item, associated_item_def_ids, associated_items, @@ -334,7 +335,7 @@ fn associated_type_for_impl_trait_in_trait( parent_count, params, param_def_id_to_index, - has_self: false, + has_self: opaque_ty_generics.has_self, has_late_bound_regions: opaque_ty_generics.has_late_bound_regions, } }); diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index 3b1abdcb2..51b908881 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -2,6 +2,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_trait_selection::traits; @@ -32,12 +33,6 @@ fn is_item_raw<'tcx>( traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, ty, trait_def_id) } -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { - is_copy_raw, - is_sized_raw, - is_freeze_raw, - is_unpin_raw, - ..*providers - }; +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index b67607a4d..1219bb400 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -2,6 +2,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::query::Providers; use rustc_middle::thir::visit; use rustc_middle::thir::visit::Visitor; use rustc_middle::ty::abstract_const::CastKind; @@ -115,9 +116,7 @@ fn recurse_build<'tcx>( let sp = node.span; match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { Ok(c) => c, - Err(LitToConstError::Reported(guar)) => { - tcx.const_error_with_guaranteed(node.ty, guar) - } + Err(LitToConstError::Reported(guar)) => tcx.const_error(node.ty, guar), Err(LitToConstError::TypeError) => { bug!("encountered type error in lit_to_const") } @@ -132,7 +131,7 @@ fn recurse_build<'tcx>( tcx.mk_const(val, node.ty) } &ExprKind::NamedConst { def_id, substs, user_ty: _ } => { - let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = ty::UnevaluatedConst::new(def_id, substs); tcx.mk_const(uneval, node.ty) } ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty), @@ -256,6 +255,7 @@ fn recurse_build<'tcx>( ExprKind::VarRef { .. } | ExprKind::UpvarRef { .. } | ExprKind::StaticRef { .. } + | ExprKind::OffsetOf { .. } | ExprKind::ThreadLocalRef(_) => { error(GenericConstantTooComplexSub::OperationNotSupported(node.span))? } @@ -347,6 +347,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { | thir::ExprKind::ZstLiteral { .. } | thir::ExprKind::StaticRef { .. } | thir::ExprKind::InlineAsm(_) + | thir::ExprKind::OffsetOf { .. } | thir::ExprKind::ThreadLocalRef(_) | thir::ExprKind::Yield { .. } => false, } @@ -391,52 +392,36 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. pub fn thir_abstract_const( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> { - if tcx.features().generic_const_exprs { - match tcx.def_kind(def.did) { - // FIXME(generic_const_exprs): We currently only do this for anonymous constants, - // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether - // we want to look into them or treat them as opaque projections. - // - // Right now we do neither of that and simply always fail to unify them. - DefKind::AnonConst | DefKind::InlineConst => (), - _ => return Ok(None), - } - - let body = tcx.thir_body(def)?; - let (body, body_id) = (&*body.0.borrow(), body.1); + def: LocalDefId, +) -> Result<Option<ty::EarlyBinder<ty::Const<'_>>>, ErrorGuaranteed> { + if !tcx.features().generic_const_exprs { + return Ok(None); + } - let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; - visit::walk_expr(&mut is_poly_vis, &body[body_id]); - if !is_poly_vis.is_poly { - return Ok(None); - } + match tcx.def_kind(def) { + // FIXME(generic_const_exprs): We currently only do this for anonymous constants, + // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether + // we want to look into them or treat them as opaque projections. + // + // Right now we do neither of that and simply always fail to unify them. + DefKind::AnonConst | DefKind::InlineConst => (), + _ => return Ok(None), + } - let root_span = body.exprs[body_id].span; + let body = tcx.thir_body(def)?; + let (body, body_id) = (&*body.0.borrow(), body.1); - Some(recurse_build(tcx, body, body_id, root_span)).transpose() - } else { - Ok(None) + let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; + visit::walk_expr(&mut is_poly_vis, &body[body_id]); + if !is_poly_vis.is_poly { + return Ok(None); } + + let root_span = body.exprs[body_id].span; + + Ok(Some(ty::EarlyBinder(recurse_build(tcx, body, body_id, root_span)?))) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { - destructure_const, - thir_abstract_const: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.thir_abstract_const_of_const_arg(def) - } else { - thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - thir_abstract_const_of_const_arg: |tcx, (did, param_did)| { - thir_abstract_const( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - ) - }, - ..*providers - }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { destructure_const, thir_abstract_const, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 3d3fc50e6..553bf40ef 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by ty_utils use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{GenericArg, Ty}; use rustc_span::Span; #[derive(Diagnostic)] @@ -100,3 +100,25 @@ pub struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_duplicate_arg)] +pub struct DuplicateArg<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_not_param)] +pub struct NotParam<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 56d6cc28b..081be0658 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,8 +1,9 @@ use rustc_hir::{def::DefKind, def_id::DefId}; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { assumed_wf_types, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { assumed_wf_types, ..*providers }; } fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { @@ -31,6 +32,18 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { } } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), + DefKind::OpaqueTy => match tcx.def_kind(tcx.parent(def_id)) { + DefKind::TyAlias => ty::List::empty(), + DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), + // Nested opaque types only occur in associated types: + // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; ` + // assumed_wf_types should include those of `Opaque<T>`, `Opaque<T>` itself + // and `&'static T`. + DefKind::OpaqueTy => bug!("unimplemented implied bounds for neseted opaque types"), + def_kind @ _ => { + bug!("unimplemented implied bounds for opaque types with parent {def_kind:?}") + } + }, DefKind::Mod | DefKind::Struct | DefKind::Union @@ -51,7 +64,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { | DefKind::ForeignMod | DefKind::AnonConst | DefKind::InlineConst - | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder | DefKind::Field | DefKind::LifetimeParam diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 0a6c11809..36a20c78f 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::query::Providers; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt}; @@ -14,54 +15,25 @@ fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, substs)) = key.into_parts(); - if let Some(did) = did.as_local() { - if let Some(param_did) = tcx.opt_const_param_of(did) { - return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs))); - } - } - - inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs))) -} - -fn resolve_instance_of_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, const_param_did, substs)) = key.into_parts(); - inner_resolve_instance( - tcx, - param_env.and(( - ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) }, - substs, - )), - ) -} - -fn inner_resolve_instance<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { let (param_env, (def, substs)) = key.into_parts(); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) { + let result = if let Some(trait_def_id) = tcx.trait_of_item(def) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); resolve_associated_item( tcx, - def.did, + def, param_env, trait_def_id, tcx.normalize_erasing_regions(param_env, substs), ) } else { - let ty = tcx.type_of(def.def_id_for_type_of()); - let item_type = - tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); + let ty = tcx.type_of(def); + let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def.did) + ty::InstanceDef::Intrinsic(def) } ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { let ty = substs.type_at(0); @@ -113,7 +85,7 @@ fn resolve_associated_item<'tcx>( Err(CodegenObligationError::Ambiguity) => { let reported = tcx.sess.delay_span_bug( tcx.def_span(trait_item_id), - &format!( + format!( "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \ overflow or prior type error", ), @@ -132,8 +104,8 @@ fn resolve_associated_item<'tcx>( "resolving ImplSource::UserDefined: {:?}, {:?}, {:?}, {:?}", param_env, trait_item_id, rcvr_substs, impl_data ); - assert!(!rcvr_substs.needs_infer()); - assert!(!trait_ref.needs_infer()); + assert!(!rcvr_substs.has_infer()); + assert!(!trait_ref.has_infer()); let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap(); let trait_def = tcx.trait_def(trait_def_id); @@ -205,19 +177,52 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } - traits::ImplSource::Generator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - generator_data.generator_def_id, - )), - substs: generator_data.substs, - }), - traits::ImplSource::Future(future_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - future_data.generator_def_id, - )), - substs: future_data.substs, - }), + traits::ImplSource::Generator(generator_data) => { + if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume { + // For compiler developers who'd like to add new items to `Generator`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + span_bug!( + tcx.def_span(generator_data.generator_def_id), + "no definition for `{trait_ref}::{}` for built-in generator type", + tcx.item_name(trait_item_id) + ) + } + Some(Instance { + def: ty::InstanceDef::Item(generator_data.generator_def_id), + substs: generator_data.substs, + }) + } + traits::ImplSource::Future(future_data) => { + if Some(trait_item_id) == tcx.lang_items().future_poll_fn() { + // `Future::poll` is generated by the compiler. + Some(Instance { + def: ty::InstanceDef::Item(future_data.generator_def_id), + substs: future_data.substs, + }) + } else { + // All other methods are default methods of the `Future` trait. + // (this assumes that `ImplSource::Future` is only used for methods on `Future`) + debug_assert!(tcx.impl_defaultness(trait_item_id).has_value()); + Some(Instance::new(trait_item_id, rcvr_substs)) + } + } traits::ImplSource::Closure(closure_data) => { + if cfg!(debug_assertions) + && ![sym::call, sym::call_mut, sym::call_once] + .contains(&tcx.item_name(trait_item_id)) + { + // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + span_bug!( + tcx.def_span(closure_data.closure_def_id), + "no definition for `{trait_ref}::{}` for built-in closure type", + tcx.item_name(trait_item_id) + ) + } let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap(); Instance::resolve_closure( tcx, @@ -227,22 +232,37 @@ fn resolve_associated_item<'tcx>( ) } traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() { - ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty), - substs: rcvr_substs, - }), - _ => None, - }, - traits::ImplSource::Object(ref data) => { - if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id) - { + ty::FnDef(..) | ty::FnPtr(..) => { + if cfg!(debug_assertions) + && ![sym::call, sym::call_mut, sym::call_once] + .contains(&tcx.item_name(trait_item_id)) + { + // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`, + // you either need to generate a shim body, or perhaps return + // `InstanceDef::Item` pointing to a trait default method body if + // it is given a default implementation by the trait. + bug!( + "no definition for `{trait_ref}::{}` for built-in fn type", + tcx.item_name(trait_item_id) + ) + } Some(Instance { - def: ty::InstanceDef::Virtual(trait_item_id, index), + def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty), substs: rcvr_substs, }) - } else { - None } + _ => bug!( + "no built-in definition for `{trait_ref}::{}` for non-fn type", + tcx.item_name(trait_item_id) + ), + }, + traits::ImplSource::Object(ref data) => { + traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| { + Instance { + def: ty::InstanceDef::Virtual(trait_item_id, index), + substs: rcvr_substs, + } + }) } traits::ImplSource::Builtin(..) => { let lang_items = tcx.lang_items(); @@ -300,7 +320,6 @@ fn resolve_associated_item<'tcx>( }) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { resolve_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 63ef1c724..16cd8bc8e 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,8 +1,9 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; +use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; @@ -22,8 +23,8 @@ use crate::errors::{ }; use crate::layout_sanity_check::sanity_check_layout; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { layout_of, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { layout_of, ..*providers }; } #[instrument(skip(tcx, query), level = "debug")] diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index a5311dbd1..c4a4cda68 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -4,7 +4,7 @@ use rustc_middle::ty::{ }; use rustc_target::abi::*; -use std::cmp; +use std::assert_matches::assert_matches; /// Enforce some basic invariants on layouts. pub(super) fn sanity_check_layout<'tcx>( @@ -68,21 +68,31 @@ pub(super) fn sanity_check_layout<'tcx>( } fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayout<'tcx>) { + // Verify the ABI mandated alignment and size. + let align = layout.abi.inherent_align(cx).map(|align| align.abi); + let size = layout.abi.inherent_size(cx); + let Some((align, size)) = align.zip(size) else { + assert_matches!( + layout.layout.abi(), + Abi::Uninhabited | Abi::Aggregate { .. }, + "ABI unexpectedly missing alignment and/or size in {layout:#?}" + ); + return + }; + assert_eq!( + layout.layout.align().abi, + align, + "alignment mismatch between ABI and layout in {layout:#?}" + ); + assert_eq!( + layout.layout.size(), + size, + "size mismatch between ABI and layout in {layout:#?}" + ); + + // Verify per-ABI invariants match layout.layout.abi() { - Abi::Scalar(scalar) => { - // No padding in scalars. - let size = scalar.size(cx); - let align = scalar.align(cx).abi; - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}" - ); + Abi::Scalar(_) => { // Check that this matches the underlying field. let inner = skip_newtypes(cx, layout); assert!( @@ -135,24 +145,6 @@ pub(super) fn sanity_check_layout<'tcx>( } } Abi::ScalarPair(scalar1, scalar2) => { - // Sanity-check scalar pairs. Computing the expected size and alignment is a bit of work. - let size1 = scalar1.size(cx); - let align1 = scalar1.align(cx).abi; - let size2 = scalar2.size(cx); - let align2 = scalar2.align(cx).abi; - let align = cmp::max(align1, align2); - let field2_offset = size1.align_to(align2); - let size = (field2_offset + size2).align_to(align); - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}", - ); // Check that the underlying pair of fields matches. let inner = skip_newtypes(cx, layout); assert!( @@ -189,8 +181,9 @@ pub(super) fn sanity_check_layout<'tcx>( "`ScalarPair` layout for type with less than two non-ZST fields: {inner:#?}" ) }); - assert!( - fields.next().is_none(), + assert_matches!( + fields.next(), + None, "`ScalarPair` layout for type with at least three non-ZST fields: {inner:#?}" ); // The fields might be in opposite order. @@ -200,6 +193,10 @@ pub(super) fn sanity_check_layout<'tcx>( (offset2, field2, offset1, field1) }; // The fields should be at the right offset, and match the `scalar` layout. + let size1 = scalar1.size(cx); + let align1 = scalar1.align(cx).abi; + let size2 = scalar2.size(cx); + let align2 = scalar2.align(cx).abi; assert_eq!( offset1, Size::ZERO, @@ -213,10 +210,12 @@ pub(super) fn sanity_check_layout<'tcx>( field1.align.abi, align1, "`ScalarPair` first field with bad align in {inner:#?}", ); - assert!( - matches!(field1.abi, Abi::Scalar(_)), + assert_matches!( + field1.abi, + Abi::Scalar(_), "`ScalarPair` first field with bad ABI in {inner:#?}", ); + let field2_offset = size1.align_to(align2); assert_eq!( offset2, field2_offset, "`ScalarPair` second field at bad offset in {inner:#?}", @@ -229,27 +228,14 @@ pub(super) fn sanity_check_layout<'tcx>( field2.align.abi, align2, "`ScalarPair` second field with bad align in {inner:#?}", ); - assert!( - matches!(field2.abi, Abi::Scalar(_)), + assert_matches!( + field2.abi, + Abi::Scalar(_), "`ScalarPair` second field with bad ABI in {inner:#?}", ); } - Abi::Vector { count, element } => { - // No padding in vectors, except possibly for trailing padding to make the size a multiple of align. - let size = element.size(cx) * count; - let align = cx.data_layout().vector_align(size).abi; - let size = size.align_to(align); // needed e.g. for vectors of size 3 + Abi::Vector { element, .. } => { assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`. - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}" - ); // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. } Abi::Uninhabited | Abi::Aggregate { .. } => {} // Nothing to check. @@ -285,7 +271,7 @@ pub(super) fn sanity_check_layout<'tcx>( { // These are never actually accessed anyway, so we can skip the coherence check // for them. They also fail that check, since they have - // `Aggregate`/`Uninhbaited` ABI even when the main type is + // `Aggregate`/`Uninhabited` ABI even when the main type is // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size // 0, and sometimes, variants without fields have non-0 size.) continue; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 2613445f3..55b8857ed 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(assert_matches)] #![feature(iterator_try_collect)] #![feature(let_chains)] #![feature(never_type)] @@ -19,8 +20,8 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; -use rustc_middle::ty::query::Providers; +use rustc_fluent_macro::fluent_messages; +use rustc_middle::query::Providers; mod abi; mod assoc; @@ -32,6 +33,7 @@ pub mod instance; mod layout; mod layout_sanity_check; mod needs_drop; +mod opaque_types; pub mod representability; mod structural_match; mod ty; @@ -46,6 +48,7 @@ pub fn provide(providers: &mut Providers) { implied_bounds::provide(providers); layout::provide(providers); needs_drop::provide(providers); + opaque_types::provide(providers); representability::provide(providers); ty::provide(providers); instance::provide(providers); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index de7fd0031..1f9701b93 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; +use rustc_middle::query::Providers; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop}; use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; @@ -132,7 +133,7 @@ where _ => { tcx.sess.delay_span_bug( tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP), - &format!("unexpected generator witness type {:?}", witness), + format!("unexpected generator witness type {:?}", witness), ); return Some(Err(AlwaysRequiresDrop)); } @@ -243,7 +244,7 @@ fn drop_tys_helper<'tcx>( } else { let field_tys = adt_def.all_fields().map(|field| { let r = tcx.type_of(field.did).subst(tcx, substs); - debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); + debug!("drop_tys_helper: Subst into {:?} with {:?} getting {:?}", field, substs, r); r }); if only_significant { @@ -323,8 +324,8 @@ fn adt_significant_drop_tys( .map(|components| tcx.mk_type_list(&components)) } -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { needs_drop_raw, has_significant_drop_raw, adt_drop_tys, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs new file mode 100644 index 000000000..4e91dd380 --- /dev/null +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -0,0 +1,198 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::ErrorGuaranteed; +use rustc_hir::{def::DefKind, def_id::LocalDefId}; +use rustc_middle::query::Providers; +use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_span::Span; +use rustc_type_ir::AliasKind; +use std::ops::ControlFlow; + +use crate::errors::{DuplicateArg, NotParam}; + +struct OpaqueTypeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + opaques: Vec<LocalDefId>, + /// The `DefId` of the item which we are collecting opaque types for. + item: LocalDefId, + + /// Avoid infinite recursion due to recursive declarations. + seen: FxHashSet<LocalDefId>, +} + +impl<'tcx> OpaqueTypeCollector<'tcx> { + fn collect( + tcx: TyCtxt<'tcx>, + item: LocalDefId, + val: ty::Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>, + ) -> Vec<LocalDefId> { + let mut collector = Self { tcx, opaques: Vec::new(), item, seen: Default::default() }; + val.skip_binder().visit_with(&mut collector); + collector.opaques + } + + fn span(&self) -> Span { + self.tcx.def_span(self.item) + } + + fn parent(&self) -> Option<LocalDefId> { + match self.tcx.def_kind(self.item) { + DefKind::Fn => None, + DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + Some(self.tcx.local_parent(self.item)) + } + other => span_bug!( + self.tcx.def_span(self.item), + "unhandled item with opaque types: {other:?}" + ), + } + } +} + +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { + type BreakTy = ErrorGuaranteed; + + #[instrument(skip(self), ret, level = "trace")] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<ErrorGuaranteed> { + match t.kind() { + ty::Alias(AliasKind::Opaque, alias_ty) if alias_ty.def_id.is_local() => { + if !self.seen.insert(alias_ty.def_id.expect_local()) { + return ControlFlow::Continue(()); + } + match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) { + Ok(()) => { + // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not + // supported at all, so this is sound to do, but once we want to support them, you'll + // start seeing the error below. + + self.opaques.push(alias_ty.def_id.expect_local()); + + // Collect opaque types nested within the associated type bounds of this opaque type. + for (pred, _span) in self + .tcx + .explicit_item_bounds(alias_ty.def_id) + .subst_iter_copied(self.tcx, alias_ty.substs) + { + trace!(?pred); + pred.visit_with(self)?; + } + + ControlFlow::Continue(()) + } + Err(NotUniqueParam::NotParam(arg)) => { + let err = self.tcx.sess.emit_err(NotParam { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) + } + Err(NotUniqueParam::DuplicateParam(arg)) => { + let err = self.tcx.sess.emit_err(DuplicateArg { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) + } + } + } + ty::Alias(AliasKind::Projection, alias_ty) => { + if let Some(parent) = self.parent() { + trace!(?alias_ty); + let (trait_ref, own_substs) = alias_ty.trait_ref_and_own_substs(self.tcx); + + trace!(?trait_ref, ?own_substs); + // This avoids having to do normalization of `Self::AssocTy` by only + // supporting the case of a method defining opaque types from assoc types + // in the same impl block. + if trait_ref.self_ty() == self.tcx.type_of(parent).subst_identity() { + for assoc in self.tcx.associated_items(parent).in_definition_order() { + trace!(?assoc); + if assoc.trait_item_def_id == Some(alias_ty.def_id) { + // We reconstruct the generic args of the associated type within the impl + // from the impl's generics and the generic args passed to the type via the + // projection. + let substs = ty::InternalSubsts::identity_for_item( + self.tcx, + parent.to_def_id(), + ); + trace!(?substs); + let substs: Vec<_> = + substs.iter().chain(own_substs.iter().copied()).collect(); + trace!(?substs); + // Find opaque types in this associated type. + return self + .tcx + .type_of(assoc.def_id) + .subst(self.tcx, &substs) + .visit_with(self); + } + } + } + } + t.super_visit_with(self) + } + _ => t.super_visit_with(self), + } + } +} + +fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { + let kind = tcx.def_kind(item); + trace!(?kind); + // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types. + match kind { + // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` + DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + let defined_opaques = match kind { + DefKind::Fn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocFn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocTy | DefKind::AssocConst => OpaqueTypeCollector::collect( + tcx, + item, + ty::Binder::dummy(tcx.type_of(item).subst_identity()), + ), + _ => unreachable!(), + }; + tcx.arena.alloc_from_iter(defined_opaques) + } + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::TyParam + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(_) + | DefKind::Ctor(_, _) + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Impl { .. } + | DefKind::Closure + | DefKind::Generator => &[], + } +} + +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { opaque_types_defined_by, ..*providers }; +} diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 26d6deab8..0b5e27c2c 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -2,7 +2,7 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index a55bb7e7e..215acbe2c 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -1,5 +1,5 @@ use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_infer::infer::TyCtxtInferExt; @@ -13,7 +13,7 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; /// Note that this does *not* recursively check if the substructure of `adt_ty` /// implements the traits. fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { - let ref infcx = tcx.infer_ctxt().build(); + let infcx = &tcx.infer_ctxt().build(); let cause = ObligationCause::dummy(); let ocx = ObligationCtxt::new(infcx); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index cb06c7acf..65dc3c39c 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; +use rustc_middle::query::Providers; use rustc_middle::ty::{ self, Binder, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, @@ -62,9 +63,8 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, [ty])) - .without_const() - .to_predicate(tcx); + let sized_predicate = + ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } @@ -567,8 +567,8 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32 unsizing_params } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub fn provide(providers: &mut Providers) { + *providers = Providers { asyncness, adt_sized_constraint, param_env, |