From 673a1ad25c02c2186ea476488a76f61d84f2f2a5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 18 Jul 2025 20:04:45 +0000 Subject: [PATCH 1/3] Remove coroutine witness type --- compiler/rustc_borrowck/src/lib.rs | 2 - .../src/value_and_place.rs | 13 - .../src/back/symbol_export.rs | 1 - .../src/debuginfo/type_names.rs | 3 +- .../src/const_eval/valtrees.rs | 2 - .../src/interpret/intrinsics.rs | 1 - .../rustc_const_eval/src/interpret/stack.rs | 1 - .../src/interpret/validity.rs | 3 +- .../rustc_const_eval/src/util/type_name.rs | 1 - .../src/coherence/inherent_impls.rs | 1 - .../src/coherence/orphan.rs | 1 - .../src/variance/constraints.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 1 - compiler/rustc_hir_typeck/src/coercion.rs | 1 - .../src/infer/canonical/canonicalizer.rs | 1 - compiler/rustc_lint/src/foreign_modules.rs | 1 - compiler/rustc_lint/src/types.rs | 703 ++++++++++++++++++ compiler/rustc_middle/src/ty/context.rs | 6 - compiler/rustc_middle/src/ty/diagnostics.rs | 2 - compiler/rustc_middle/src/ty/error.rs | 2 - compiler/rustc_middle/src/ty/layout.rs | 1 - compiler/rustc_middle/src/ty/opaque_types.rs | 5 - compiler/rustc_middle/src/ty/print/mod.rs | 1 - compiler/rustc_middle/src/ty/print/pretty.rs | 38 +- .../src/ty/significant_drop_order.rs | 1 - .../rustc_middle/src/ty/structural_impls.rs | 5 - compiler/rustc_middle/src/ty/sty.rs | 59 +- compiler/rustc_middle/src/ty/util.rs | 6 +- .../src/move_paths/builder.rs | 2 - .../src/dataflow_const_prop.rs | 2 +- .../src/canonical/canonicalizer.rs | 1 - .../src/solve/assembly/mod.rs | 2 - .../src/solve/assembly/structural_traits.rs | 54 +- .../src/solve/normalizes_to/mod.rs | 2 - .../src/solve/trait_goals.rs | 4 +- compiler/rustc_passes/src/check_export.rs | 1 - compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 3 +- .../rustc_public/src/compiler_interface.rs | 1 - compiler/rustc_public/src/lib.rs | 1 - compiler/rustc_public/src/ty.rs | 6 - .../src/unstable/convert/internal.rs | 5 +- .../src/unstable/convert/stable/ty.rs | 4 - compiler/rustc_public/src/visitor.rs | 1 - compiler/rustc_public_bridge/src/bridge.rs | 1 - compiler/rustc_public_bridge/src/lib.rs | 8 - .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 7 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 1 - compiler/rustc_symbol_mangling/src/export.rs | 1 - compiler/rustc_symbol_mangling/src/v0.rs | 1 - .../traits/fulfillment_errors.rs | 7 +- .../src/error_reporting/traits/suggestions.rs | 8 +- .../src/traits/effects.rs | 7 +- .../src/traits/project.rs | 2 - .../src/traits/query/dropck_outlives.rs | 4 +- .../src/traits/select/candidate_assembly.rs | 16 - .../src/traits/select/confirmation.rs | 1 - .../src/traits/select/mod.rs | 53 +- .../rustc_trait_selection/src/traits/wf.rs | 1 - compiler/rustc_ty_utils/src/instance.rs | 1 - compiler/rustc_ty_utils/src/layout.rs | 2 +- compiler/rustc_ty_utils/src/needs_drop.rs | 4 - compiler/rustc_ty_utils/src/ty.rs | 2 - compiler/rustc_type_ir/src/fast_reject.rs | 13 +- compiler/rustc_type_ir/src/flags.rs | 4 +- compiler/rustc_type_ir/src/inherent.rs | 9 - compiler/rustc_type_ir/src/outlives.rs | 4 - compiler/rustc_type_ir/src/relate.rs | 10 - compiler/rustc_type_ir/src/ty_kind.rs | 27 - compiler/rustc_type_ir/src/walk.rs | 1 - tests/debuginfo/function-names.rs | 1 + .../partial-drop-partial-reinit.rs | 1 - .../partial-drop-partial-reinit.stderr | 4 +- tests/ui/symbol-names/basic.legacy.stderr | 4 +- .../ui/symbol-names/issue-60925.legacy.stderr | 4 +- 75 files changed, 794 insertions(+), 370 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 91defbad0a0e0..11de6e58ac366 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1882,7 +1882,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::UnsafeBinder(_) @@ -1925,7 +1924,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::FnDef(_, _) | ty::FnPtr(..) | ty::Dynamic(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::UnsafeBinder(_) | ty::Alias(_, _) diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 5b76a4cb97793..ddd7e9ef58086 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -973,19 +973,6 @@ pub(crate) fn assert_assignable<'tcx>( } } } - (&ty::CoroutineWitness(def_id_a, args_a), &ty::CoroutineWitness(def_id_b, args_b)) - if def_id_a == def_id_b => - { - let mut types_a = args_a.types(); - let mut types_b = args_b.types(); - loop { - match (types_a.next(), types_b.next()) { - (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1), - (None, None) => return, - (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty), - } - } - } _ => { assert_eq!( from_ty, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 27989f6f5ea24..ffa097b0324af 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -253,7 +253,6 @@ fn exported_generic_symbols_provider_local<'tcx>( ty::FnDef(def_id, _) => *def_id, ty::Coroutine(def_id, _) => *def_id, ty::CoroutineClosure(def_id, _) => *def_id, - ty::CoroutineWitness(def_id, _) => *def_id, _ => return false, }; let Some(root_def_id) = root_def_id.as_local() else { diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 02476a3322527..4d14b2982da0f 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -437,8 +437,7 @@ fn push_debuginfo_type_name<'tcx>( | ty::Infer(_) | ty::Placeholder(..) | ty::Alias(..) - | ty::Bound(..) - | ty::CoroutineWitness(..) => { + | ty::Bound(..) => { bug!( "debuginfo: Trying to create type name for \ unexpected type: {:?}", diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index b771addb8df55..910ae93dee0e2 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -181,7 +181,6 @@ fn const_to_valtree_inner<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) => Err(ValTreeCreationError::NonSupportedType(ty)), } } @@ -343,7 +342,6 @@ pub fn valtree_to_const_value<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::FnPtr(..) | ty::Str | ty::Slice(_) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index fe1dd1b6eb352..0fb598bae51cb 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -297,7 +297,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 1c1c59da9d886..7b73fe98aab37 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -502,7 +502,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 5d8ae42f5eccd..f549be8bf47e8 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -794,8 +794,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { | ty::Placeholder(..) | ty::Bound(..) | ty::Param(..) - | ty::Alias(..) - | ty::CoroutineWitness(..) => bug!("Encountered invalid type {:?}", ty), + | ty::Alias(..) => bug!("Encountered invalid type {:?}", ty), } } diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index db651811551f3..4bdfbd1d4bb20 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -61,7 +61,6 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> { ty::Alias(ty::Free, _) => bug!("type_name: unexpected free alias"), ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"), - ty::CoroutineWitness(..) => bug!("type_name: unexpected `CoroutineWitness`"), } } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index fe47f3258846d..ebf0316a20046 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -197,7 +197,6 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Alias(ty::Free, _) | ty::Bound(..) | ty::Placeholder(_) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index f1e138dbcb97a..e3b36b06ff29d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -226,7 +226,6 @@ pub(crate) fn orphan_check_impl( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index ce4668736b570..a573ac1acd0c6 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -323,7 +323,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // types, where we use Error as the Self type } - ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Bound(..) | ty::Infer(..) => { + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { bug!("unexpected type encountered in variance inference: {}", ty); } } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 3f13a102684e0..70c47bdea2a66 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -133,7 +133,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Uint(..) | ty::Float(_) | ty::Array(..) - | ty::CoroutineWitness(..) | ty::RawPtr(_, _) | ty::Ref(..) | ty::Pat(..) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 52ea6cdeaa0eb..bbb05f4d9daae 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -554,7 +554,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::Tuple(_) => return Err(TypeError::Mismatch), _ => {} diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 23f6fee406a55..b7bf41b16dc52 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -398,7 +398,6 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Bool | ty::Char | ty::Int(..) diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index ad73e15e31f37..f094c32cb48fd 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -358,7 +358,6 @@ fn structurally_same_type_impl<'tcx>( | (ty::Error(..), ty::Error(..)) | (ty::Closure(..), ty::Closure(..)) | (ty::Coroutine(..), ty::Coroutine(..)) - | (ty::CoroutineWitness(..), ty::CoroutineWitness(..)) | (ty::Alias(ty::Projection, ..), ty::Alias(ty::Projection, ..)) | (ty::Alias(ty::Inherent, ..), ty::Alias(ty::Inherent, ..)) | (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => false, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f3e6db6f2d8e4..4cd34361e5a8b 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -931,6 +931,709 @@ fn get_nullable_type_from_pat<'tcx>( } } +impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { + /// Check if the type is array and emit an unsafe type lint. + fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { + if let ty::Array(..) = ty.kind() { + self.emit_ffi_unsafe_type_lint( + ty, + sp, + fluent::lint_improper_ctypes_array_reason, + Some(fluent::lint_improper_ctypes_array_help), + ); + true + } else { + false + } + } + + /// Checks if the given field's type is "ffi-safe". + fn check_field_type_for_ffi( + &self, + acc: &mut CTypesVisitorState<'tcx>, + field: &ty::FieldDef, + args: GenericArgsRef<'tcx>, + ) -> FfiResult<'tcx> { + let field_ty = field.ty(self.cx.tcx, args); + let field_ty = self + .cx + .tcx + .try_normalize_erasing_regions(self.cx.typing_env(), field_ty) + .unwrap_or(field_ty); + self.check_type_for_ffi(acc, field_ty) + } + + /// Checks if the given `VariantDef`'s field types are "ffi-safe". + fn check_variant_for_ffi( + &self, + acc: &mut CTypesVisitorState<'tcx>, + ty: Ty<'tcx>, + def: ty::AdtDef<'tcx>, + variant: &ty::VariantDef, + args: GenericArgsRef<'tcx>, + ) -> FfiResult<'tcx> { + use FfiResult::*; + let transparent_with_all_zst_fields = if def.repr().transparent() { + if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { + // Transparent newtypes have at most one non-ZST field which needs to be checked.. + match self.check_field_type_for_ffi(acc, field, args) { + FfiUnsafe { ty, .. } if ty.is_unit() => (), + r => return r, + } + + false + } else { + // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all + // `PhantomData`). + true + } + } else { + false + }; + + // We can't completely trust `repr(C)` markings, so make sure the fields are actually safe. + let mut all_phantom = !variant.fields.is_empty(); + for field in &variant.fields { + all_phantom &= match self.check_field_type_for_ffi(acc, field, args) { + FfiSafe => false, + // `()` fields are FFI-safe! + FfiUnsafe { ty, .. } if ty.is_unit() => false, + FfiPhantom(..) => true, + r @ FfiUnsafe { .. } => return r, + } + } + + if all_phantom { + FfiPhantom(ty) + } else if transparent_with_all_zst_fields { + FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_struct_zst, help: None } + } else { + FfiSafe + } + } + + /// Checks if the given type is "ffi-safe" (has a stable, well-defined + /// representation which can be exported to C code). + fn check_type_for_ffi( + &self, + acc: &mut CTypesVisitorState<'tcx>, + ty: Ty<'tcx>, + ) -> FfiResult<'tcx> { + use FfiResult::*; + + let tcx = self.cx.tcx; + + // Protect against infinite recursion, for example + // `struct S(*mut S);`. + // FIXME: A recursion limit is necessary as well, for irregular + // recursive types. + if !acc.cache.insert(ty) { + return FfiSafe; + } + + match *ty.kind() { + ty::Adt(def, args) => { + if let Some(boxed) = ty.boxed_ty() + && matches!(self.mode, CItemKind::Definition) + { + if boxed.is_sized(tcx, self.cx.typing_env()) { + return FfiSafe; + } else { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_box, + help: None, + }; + } + } + if def.is_phantom_data() { + return FfiPhantom(ty); + } + match def.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + if let Some(sym::cstring_type | sym::cstr_type) = + tcx.get_diagnostic_name(def.did()) + && !acc.base_ty.is_mutable_ptr() + { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_cstr_reason, + help: Some(fluent::lint_improper_ctypes_cstr_help), + }; + } + + if !def.repr().c() && !def.repr().transparent() { + return FfiUnsafe { + ty, + reason: if def.is_struct() { + fluent::lint_improper_ctypes_struct_layout_reason + } else { + fluent::lint_improper_ctypes_union_layout_reason + }, + help: if def.is_struct() { + Some(fluent::lint_improper_ctypes_struct_layout_help) + } else { + Some(fluent::lint_improper_ctypes_union_layout_help) + }, + }; + } + + if def.non_enum_variant().field_list_has_applicable_non_exhaustive() { + return FfiUnsafe { + ty, + reason: if def.is_struct() { + fluent::lint_improper_ctypes_struct_non_exhaustive + } else { + fluent::lint_improper_ctypes_union_non_exhaustive + }, + help: None, + }; + } + + if def.non_enum_variant().fields.is_empty() { + return FfiUnsafe { + ty, + reason: if def.is_struct() { + fluent::lint_improper_ctypes_struct_fieldless_reason + } else { + fluent::lint_improper_ctypes_union_fieldless_reason + }, + help: if def.is_struct() { + Some(fluent::lint_improper_ctypes_struct_fieldless_help) + } else { + Some(fluent::lint_improper_ctypes_union_fieldless_help) + }, + }; + } + + self.check_variant_for_ffi(acc, ty, def, def.non_enum_variant(), args) + } + AdtKind::Enum => { + if def.variants().is_empty() { + // Empty enums are okay... although sort of useless. + return FfiSafe; + } + // Check for a repr() attribute to specify the size of the + // discriminant. + if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none() + { + // Special-case types like `Option` and `Result` + if let Some(ty) = + repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode) + { + return self.check_type_for_ffi(acc, ty); + } + + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_enum_repr_reason, + help: Some(fluent::lint_improper_ctypes_enum_repr_help), + }; + } + + use improper_ctypes::check_non_exhaustive_variant; + + let non_exhaustive = def.variant_list_has_applicable_non_exhaustive(); + // Check the contained variants. + let ret = def.variants().iter().try_for_each(|variant| { + check_non_exhaustive_variant(non_exhaustive, variant) + .map_break(|reason| FfiUnsafe { ty, reason, help: None })?; + + match self.check_variant_for_ffi(acc, ty, def, variant, args) { + FfiSafe => ControlFlow::Continue(()), + r => ControlFlow::Break(r), + } + }); + if let ControlFlow::Break(result) = ret { + return result; + } + + FfiSafe + } + } + } + + ty::Char => FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_char_reason, + help: Some(fluent::lint_improper_ctypes_char_help), + }, + + // It's just extra invariants on the type that you need to uphold, + // but only the base type is relevant for being representable in FFI. + ty::Pat(base, ..) => self.check_type_for_ffi(acc, base), + + // Primitive types with a stable representation. + ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe, + + ty::Slice(_) => FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_slice_reason, + help: Some(fluent::lint_improper_ctypes_slice_help), + }, + + ty::Dynamic(..) => { + FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_dyn, help: None } + } + + ty::Str => FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_str_reason, + help: Some(fluent::lint_improper_ctypes_str_help), + }, + + ty::Tuple(..) => FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_tuple_reason, + help: Some(fluent::lint_improper_ctypes_tuple_help), + }, + + ty::RawPtr(ty, _) | ty::Ref(_, ty, _) + if { + matches!(self.mode, CItemKind::Definition) + && ty.is_sized(self.cx.tcx, self.cx.typing_env()) + } => + { + FfiSafe + } + + ty::RawPtr(ty, _) + if match ty.kind() { + ty::Tuple(tuple) => tuple.is_empty(), + _ => false, + } => + { + FfiSafe + } + + ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(acc, ty), + + ty::Array(inner_ty, _) => self.check_type_for_ffi(acc, inner_ty), + + ty::FnPtr(sig_tys, hdr) => { + let sig = sig_tys.with(hdr); + if sig.abi().is_rustic_abi() { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_fnptr_reason, + help: Some(fluent::lint_improper_ctypes_fnptr_help), + }; + } + + let sig = tcx.instantiate_bound_regions_with_erased(sig); + for arg in sig.inputs() { + match self.check_type_for_ffi(acc, *arg) { + FfiSafe => {} + r => return r, + } + } + + let ret_ty = sig.output(); + if ret_ty.is_unit() { + return FfiSafe; + } + + self.check_type_for_ffi(acc, ret_ty) + } + + ty::Foreign(..) => FfiSafe, + + // While opaque types are checked for earlier, if a projection in a struct field + // normalizes to an opaque type, then it will reach this branch. + ty::Alias(ty::Opaque, ..) => { + FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_opaque, help: None } + } + + // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, + // so they are currently ignored for the purposes of this lint. + ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent, ..) + if matches!(self.mode, CItemKind::Definition) => + { + FfiSafe + } + + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + + ty::Param(..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) + | ty::Infer(..) + | ty::Bound(..) + | ty::Error(_) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::Placeholder(..) + | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty), + } + } + + fn emit_ffi_unsafe_type_lint( + &mut self, + ty: Ty<'tcx>, + sp: Span, + note: DiagMessage, + help: Option, + ) { + let lint = match self.mode { + CItemKind::Declaration => IMPROPER_CTYPES, + CItemKind::Definition => IMPROPER_CTYPES_DEFINITIONS, + }; + let desc = match self.mode { + CItemKind::Declaration => "block", + CItemKind::Definition => "fn", + }; + let span_note = if let ty::Adt(def, _) = ty.kind() + && let Some(sp) = self.cx.tcx.hir_span_if_local(def.did()) + { + Some(sp) + } else { + None + }; + self.cx.emit_span_lint( + lint, + sp, + ImproperCTypes { ty, desc, label: sp, help, note, span_note }, + ); + } + + fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { + struct ProhibitOpaqueTypes; + impl<'tcx> ty::TypeVisitor> for ProhibitOpaqueTypes { + type Result = ControlFlow>; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if !ty.has_opaque_types() { + return ControlFlow::Continue(()); + } + + if let ty::Alias(ty::Opaque, ..) = ty.kind() { + ControlFlow::Break(ty) + } else { + ty.super_visit_with(self) + } + } + } + + if let Some(ty) = self + .cx + .tcx + .try_normalize_erasing_regions(self.cx.typing_env(), ty) + .unwrap_or(ty) + .visit_with(&mut ProhibitOpaqueTypes) + .break_value() + { + self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint_improper_ctypes_opaque, None); + true + } else { + false + } + } + + fn check_type_for_ffi_and_report_errors( + &mut self, + sp: Span, + ty: Ty<'tcx>, + is_static: bool, + is_return_type: bool, + ) { + if self.check_for_opaque_ty(sp, ty) { + // We've already emitted an error due to an opaque type. + return; + } + + let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty); + + // C doesn't really support passing arrays by value - the only way to pass an array by value + // is through a struct. So, first test that the top level isn't an array, and then + // recursively check the types inside. + if !is_static && self.check_for_array_ty(sp, ty) { + return; + } + + // Don't report FFI errors for unit return types. This check exists here, and not in + // the caller (where it would make more sense) so that normalization has definitely + // happened. + if is_return_type && ty.is_unit() { + return; + } + + let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty }; + match self.check_type_for_ffi(&mut acc, ty) { + FfiResult::FfiSafe => {} + FfiResult::FfiPhantom(ty) => { + self.emit_ffi_unsafe_type_lint( + ty, + sp, + fluent::lint_improper_ctypes_only_phantomdata, + None, + ); + } + FfiResult::FfiUnsafe { ty, reason, help } => { + self.emit_ffi_unsafe_type_lint(ty, sp, reason, help); + } + } + } + + /// Check if a function's argument types and result type are "ffi-safe". + /// + /// For a external ABI function, argument types and the result type are walked to find fn-ptr + /// types that have external ABIs, as these still need checked. + fn check_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) { + let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = self.cx.tcx.instantiate_bound_regions_with_erased(sig); + + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { + for (fn_ptr_ty, span) in self.find_fn_ptr_ty_with_external_abi(input_hir, *input_ty) { + self.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, false, false); + } + } + + if let hir::FnRetTy::Return(ret_hir) = decl.output { + for (fn_ptr_ty, span) in self.find_fn_ptr_ty_with_external_abi(ret_hir, sig.output()) { + self.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, false, true); + } + } + } + + /// Check if a function's argument types and result type are "ffi-safe". + fn check_foreign_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) { + let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = self.cx.tcx.instantiate_bound_regions_with_erased(sig); + + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { + self.check_type_for_ffi_and_report_errors(input_hir.span, *input_ty, false, false); + } + + if let hir::FnRetTy::Return(ret_hir) = decl.output { + self.check_type_for_ffi_and_report_errors(ret_hir.span, sig.output(), false, true); + } + } + + fn check_foreign_static(&mut self, id: hir::OwnerId, span: Span) { + let ty = self.cx.tcx.type_of(id).instantiate_identity(); + self.check_type_for_ffi_and_report_errors(span, ty, true, false); + } + + /// Find any fn-ptr types with external ABIs in `ty`. + /// + /// For example, `Option` returns `extern "C" fn()` + fn find_fn_ptr_ty_with_external_abi( + &self, + hir_ty: &hir::Ty<'tcx>, + ty: Ty<'tcx>, + ) -> Vec<(Ty<'tcx>, Span)> { + struct FnPtrFinder<'tcx> { + spans: Vec, + tys: Vec>, + } + + impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> { + fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) { + debug!(?ty); + if let hir::TyKind::FnPtr(hir::FnPtrTy { abi, .. }) = ty.kind + && !abi.is_rustic_abi() + { + self.spans.push(ty.span); + } + + hir::intravisit::walk_ty(self, ty) + } + } + + impl<'tcx> ty::TypeVisitor> for FnPtrFinder<'tcx> { + type Result = (); + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if let ty::FnPtr(_, hdr) = ty.kind() + && !hdr.abi.is_rustic_abi() + { + self.tys.push(ty); + } + + ty.super_visit_with(self) + } + } + + let mut visitor = FnPtrFinder { spans: Vec::new(), tys: Vec::new() }; + ty.visit_with(&mut visitor); + visitor.visit_ty_unambig(hir_ty); + + iter::zip(visitor.tys.drain(..), visitor.spans.drain(..)).collect() + } +} + +impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { + fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; + let abi = cx.tcx.hir_get_foreign_abi(it.hir_id()); + + match it.kind { + hir::ForeignItemKind::Fn(sig, _, _) => { + if abi.is_rustic_abi() { + vis.check_fn(it.owner_id.def_id, sig.decl) + } else { + vis.check_foreign_fn(it.owner_id.def_id, sig.decl); + } + } + hir::ForeignItemKind::Static(ty, _, _) if !abi.is_rustic_abi() => { + vis.check_foreign_static(it.owner_id, ty.span); + } + hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (), + } + } +} + +impl ImproperCTypesDefinitions { + fn check_ty_maybe_containing_foreign_fnptr<'tcx>( + &mut self, + cx: &LateContext<'tcx>, + hir_ty: &'tcx hir::Ty<'_>, + ty: Ty<'tcx>, + ) { + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; + for (fn_ptr_ty, span) in vis.find_fn_ptr_ty_with_external_abi(hir_ty, ty) { + vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false); + } + } + + fn check_arg_for_power_alignment<'tcx>( + &mut self, + cx: &LateContext<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + assert!(cx.tcx.sess.target.os == "aix"); + // Structs (under repr(C)) follow the power alignment rule if: + // - the first field of the struct is a floating-point type that + // is greater than 4-bytes, or + // - the first field of the struct is an aggregate whose + // recursively first field is a floating-point type greater than + // 4 bytes. + if ty.is_floating_point() && ty.primitive_size(cx.tcx).bytes() > 4 { + return true; + } else if let Adt(adt_def, _) = ty.kind() + && adt_def.is_struct() + && adt_def.repr().c() + && !adt_def.repr().packed() + && adt_def.repr().align.is_none() + { + let struct_variant = adt_def.variant(VariantIdx::ZERO); + // Within a nested struct, all fields are examined to correctly + // report if any fields after the nested struct within the + // original struct are misaligned. + for struct_field in &struct_variant.fields { + let field_ty = cx.tcx.type_of(struct_field.did).instantiate_identity(); + if self.check_arg_for_power_alignment(cx, field_ty) { + return true; + } + } + } + return false; + } + + fn check_struct_for_power_alignment<'tcx>( + &mut self, + cx: &LateContext<'tcx>, + item: &'tcx hir::Item<'tcx>, + ) { + let adt_def = cx.tcx.adt_def(item.owner_id.to_def_id()); + // repr(C) structs also with packed or aligned representation + // should be ignored. + if adt_def.repr().c() + && !adt_def.repr().packed() + && adt_def.repr().align.is_none() + && cx.tcx.sess.target.os == "aix" + && !adt_def.all_fields().next().is_none() + { + let struct_variant_data = item.expect_struct().2; + for field_def in struct_variant_data.fields().iter().skip(1) { + // Struct fields (after the first field) are checked for the + // power alignment rule, as fields after the first are likely + // to be the fields that are misaligned. + let def_id = field_def.def_id; + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + if self.check_arg_for_power_alignment(cx, ty) { + cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment); + } + } + } + } +} + +/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in +/// `extern "C" { }` blocks): +/// +/// - `extern "" fn` definitions are checked in the same way as the +/// `ImproperCtypesDeclarations` visitor checks functions if `` is external (e.g. "C"). +/// - All other items which contain types (e.g. other functions, struct definitions, etc) are +/// checked for extern fn-ptrs with external ABIs. +impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + match item.kind { + hir::ItemKind::Static(_, _, ty, _) + | hir::ItemKind::Const(_, _, ty, _) + | hir::ItemKind::TyAlias(_, _, ty) => { + self.check_ty_maybe_containing_foreign_fnptr( + cx, + ty, + cx.tcx.type_of(item.owner_id).instantiate_identity(), + ); + } + // See `check_fn`.. + hir::ItemKind::Fn { .. } => {} + // Structs are checked based on if they follow the power alignment + // rule (under repr(C)). + hir::ItemKind::Struct(..) => { + self.check_struct_for_power_alignment(cx, item); + } + // See `check_field_def`.. + hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {} + // Doesn't define something that can contain a external type to be checked. + hir::ItemKind::Impl(..) + | hir::ItemKind::TraitAlias(..) + | hir::ItemKind::Trait(..) + | hir::ItemKind::GlobalAsm { .. } + | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Mod(..) + | hir::ItemKind::Macro(..) + | hir::ItemKind::Use(..) + | hir::ItemKind::ExternCrate(..) => {} + } + } + + fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'tcx>) { + self.check_ty_maybe_containing_foreign_fnptr( + cx, + field.ty, + cx.tcx.type_of(field.def_id).instantiate_identity(), + ); + } + + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: hir::intravisit::FnKind<'tcx>, + decl: &'tcx hir::FnDecl<'_>, + _: &'tcx hir::Body<'_>, + _: Span, + id: LocalDefId, + ) { + use hir::intravisit::FnKind; + + let abi = match kind { + FnKind::ItemFn(_, _, header, ..) => header.abi, + FnKind::Method(_, sig, ..) => sig.header.abi, + _ => return, + }; + + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; + if abi.is_rustic_abi() { + vis.check_fn(id, decl); + } else { + vis.check_foreign_fn(id, decl); + } + } +} + declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a3eec72214c06..cb236207abafa 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -649,11 +649,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { // `assemble_candidates_after_normalizing_self_ty`. ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (), - // FIXME: These should ideally not exist as a self type. It would be nice for - // the builtin auto trait impls of coroutines to instead directly recurse - // into the witness. - ty::CoroutineWitness(..) => (), - // These variants should not exist as a self type. ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Param(_) @@ -2632,7 +2627,6 @@ impl<'tcx> TyCtxt<'tcx> { UnsafeBinder, Placeholder, Coroutine, - CoroutineWitness, Dynamic, Closure, CoroutineClosure, diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 279c34cb275d9..2291ea41d360b 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -617,7 +617,6 @@ impl<'tcx> TypeVisitor> for IsSuggestableVisitor<'tcx> { | Closure(..) | Infer(..) | Coroutine(..) - | CoroutineWitness(..) | Bound(_, _) | Placeholder(_) | Error(_) => { @@ -702,7 +701,6 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { | FnDef(..) | Infer(..) | Coroutine(..) - | CoroutineWitness(..) | Bound(_, _) | Placeholder(_) | Error(_) => { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 66542525d2841..c3ee70253eb16 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -139,7 +139,6 @@ impl<'tcx> Ty<'tcx> { ty::Coroutine(def_id, ..) => { format!("{:#}", tcx.coroutine_kind(def_id).unwrap()).into() } - ty::CoroutineWitness(..) => "coroutine witness".into(), ty::Infer(ty::TyVar(_)) => "inferred type".into(), ty::Infer(ty::IntVar(_)) => "integer".into(), ty::Infer(ty::FloatVar(_)) => "floating-point number".into(), @@ -205,7 +204,6 @@ impl<'tcx> Ty<'tcx> { ty::Coroutine(def_id, ..) => { format!("{:#}", tcx.coroutine_kind(def_id).unwrap()).into() } - ty::CoroutineWitness(..) => "coroutine witness".into(), ty::Tuple(..) => "tuple".into(), ty::Placeholder(..) => "higher-ranked type".into(), ty::Bound(..) => "bound type variable".into(), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 81b8142d03f37..23cf59ce4b1de 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -841,7 +841,6 @@ where | ty::FnPtr(..) | ty::Never | ty::FnDef(..) - | ty::CoroutineWitness(..) | ty::Foreign(..) | ty::Dynamic(_, _) => { bug!("TyAndLayout::field({:?}): not applicable", this) diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 2b024b7b6cbb3..75b3fe7c3719e 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -155,11 +155,6 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { Ty::new_coroutine(self.tcx, def_id, args) } - ty::CoroutineWitness(def_id, args) => { - let args = self.fold_closure_args(def_id, args); - Ty::new_coroutine_witness(self.tcx, def_id, args) - } - ty::Param(param) => { // Look it up in the generic parameters list. match self.map.get(&ty.into()).map(|arg| arg.kind()) { diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 0fd68e74e0441..84a5ed99c677e 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -311,7 +311,6 @@ fn characteristic_def_id_of_type_cached<'a>( | ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) | ty::Coroutine(def_id, _) - | ty::CoroutineWitness(def_id, _) | ty::Foreign(def_id) => Some(def_id), ty::Bool diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2a65517de4033..ac12706995cd7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -910,29 +910,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { write!(self, "}}")? } - ty::CoroutineWitness(did, args) => { - write!(self, "{{")?; - if !self.tcx().sess.verbose_internals() { - write!(self, "coroutine witness")?; - if let Some(did) = did.as_local() { - let span = self.tcx().def_span(did); - write!( - self, - "@{}", - // This may end up in stderr diagnostics but it may also be emitted - // into MIR. Hence we use the remapped path if available - self.tcx().sess.source_map().span_to_diagnostic_string(span) - )?; - } else { - write!(self, "@")?; - self.print_def_path(did, args)?; - } - } else { - self.print_def_path(did, args)?; - } - - write!(self, "}}")? - } ty::Closure(did, args) => { write!(self, "{{")?; if !self.should_print_verbose() { @@ -1024,6 +1001,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(did, args)?; } } else { +<<<<<<< HEAD self.print_def_path(did, args)?; write!(self, " closure_kind_ty=")?; args.as_coroutine_closure().kind_ty().print(self)?; @@ -1033,6 +1011,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { args.as_coroutine_closure().tupled_upvars_ty().print(self)?; write!(self, " coroutine_captures_by_ref_ty=")?; args.as_coroutine_closure().coroutine_captures_by_ref_ty().print(self)?; +======= + p!(print_def_path(did, args)); + p!( + " closure_kind_ty=", + print(args.as_coroutine_closure().kind_ty()), + " signature_parts_ty=", + print(args.as_coroutine_closure().signature_parts_ty()), + " upvar_tys=", + print(args.as_coroutine_closure().tupled_upvars_ty()), + " coroutine_captures_by_ref_ty=", + print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()) + ); +>>>>>>> 3995d8bfb2b (Remove coroutine witness type) } write!(self, "}}")?; } @@ -2293,7 +2284,6 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Tuple(_) | ty::Alias(..) | ty::Param(_) diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs index f1aa7076d98ac..00ea19d97bc92 100644 --- a/compiler/rustc_middle/src/ty/significant_drop_order.rs +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -150,7 +150,6 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { } } ty::Coroutine(did, _) - | ty::CoroutineWitness(did, _) | ty::CoroutineClosure(did, _) | ty::Closure(did, _) | ty::FnDef(did, _) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 314d2ba396327..92e2d2334d472 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -391,9 +391,6 @@ impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) } ty::Coroutine(did, args) => ty::Coroutine(did, args.try_fold_with(folder)?), - ty::CoroutineWitness(did, args) => { - ty::CoroutineWitness(did, args.try_fold_with(folder)?) - } ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?), ty::CoroutineClosure(did, args) => { ty::CoroutineClosure(did, args.try_fold_with(folder)?) @@ -434,7 +431,6 @@ impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { ty::UnsafeBinder(f) => ty::UnsafeBinder(f.fold_with(folder)), ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl), ty::Coroutine(did, args) => ty::Coroutine(did, args.fold_with(folder)), - ty::CoroutineWitness(did, args) => ty::CoroutineWitness(did, args.fold_with(folder)), ty::Closure(did, args) => ty::Closure(did, args.fold_with(folder)), ty::CoroutineClosure(did, args) => ty::CoroutineClosure(did, args.fold_with(folder)), ty::Alias(kind, data) => ty::Alias(kind, data.fold_with(folder)), @@ -482,7 +478,6 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { ty.visit_with(visitor) } ty::Coroutine(_did, args) => args.visit_with(visitor), - ty::CoroutineWitness(_did, args) => args.visit_with(visitor), ty::Closure(_did, args) => args.visit_with(visitor), ty::CoroutineClosure(_did, args) => args.visit_with(visitor), ty::Alias(_, data) => data.visit_with(visitor), diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c282f2211f650..166ead664133e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -835,43 +835,6 @@ impl<'tcx> Ty<'tcx> { Ty::new(tcx, Coroutine(def_id, coroutine_args)) } - #[inline] - pub fn new_coroutine_witness( - tcx: TyCtxt<'tcx>, - def_id: DefId, - args: GenericArgsRef<'tcx>, - ) -> Ty<'tcx> { - if cfg!(debug_assertions) { - tcx.debug_assert_args_compatible(tcx.typeck_root_def_id(def_id), args); - } - Ty::new(tcx, CoroutineWitness(def_id, args)) - } - - pub fn new_coroutine_witness_for_coroutine( - tcx: TyCtxt<'tcx>, - def_id: DefId, - coroutine_args: GenericArgsRef<'tcx>, - ) -> Ty<'tcx> { - tcx.debug_assert_args_compatible(def_id, coroutine_args); - // HACK: Coroutine witness types are lifetime erased, so they - // never reference any lifetime args from the coroutine. We erase - // the regions here since we may get into situations where a - // coroutine is recursively contained within itself, leading to - // witness types that differ by region args. This means that - // cycle detection in fulfillment will not kick in, which leads - // to unnecessary overflows in async code. See the issue: - // . - let args = - ty::GenericArgs::for_item(tcx, tcx.typeck_root_def_id(def_id), |def, _| { - match def.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Type { .. } - | ty::GenericParamDefKind::Const { .. } => coroutine_args[def.index as usize], - } - }); - Ty::new_coroutine_witness(tcx, def_id, args) - } - // misc #[inline] @@ -1026,22 +989,6 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { Ty::new_closure(interner, def_id, args) } - fn new_coroutine_witness( - interner: TyCtxt<'tcx>, - def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> Self { - Ty::new_coroutine_witness(interner, def_id, args) - } - - fn new_coroutine_witness_for_coroutine( - interner: TyCtxt<'tcx>, - def_id: DefId, - coroutine_args: ty::GenericArgsRef<'tcx>, - ) -> Self { - Ty::new_coroutine_witness_for_coroutine(interner, def_id, coroutine_args) - } - fn new_ptr(interner: TyCtxt<'tcx>, ty: Self, mutbl: hir::Mutability) -> Self { Ty::new_ptr(interner, ty, mutbl) } @@ -1691,7 +1638,6 @@ impl<'tcx> Ty<'tcx> { | ty::Dynamic(..) | ty::Closure(..) | ty::CoroutineClosure(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::UnsafeBinder(_) @@ -1727,7 +1673,6 @@ impl<'tcx> Ty<'tcx> { | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -1918,7 +1863,6 @@ impl<'tcx> Ty<'tcx> { | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Pat(..) | ty::Closure(..) @@ -1994,7 +1938,7 @@ impl<'tcx> Ty<'tcx> { // for all unsized types. ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => true, - ty::Coroutine(..) | ty::CoroutineWitness(..) => false, + ty::Coroutine(..) => false, // Might be, but not "trivial" so just giving the safe answer. ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) => false, @@ -2050,7 +1994,6 @@ impl<'tcx> Ty<'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Alias(..) | ty::Error(_) => false, } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 2797f2fcdb72e..46366d5345a41 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1185,7 +1185,6 @@ impl<'tcx> Ty<'tcx> { | ty::Dynamic(..) | ty::Foreign(_) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) | ty::Infer(_) | ty::Alias(..) @@ -1226,7 +1225,6 @@ impl<'tcx> Ty<'tcx> { | ty::Dynamic(..) | ty::Foreign(_) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) | ty::Infer(_) | ty::Alias(..) @@ -1281,7 +1279,6 @@ impl<'tcx> Ty<'tcx> { | ty::Dynamic(..) | ty::Foreign(_) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Alias(..) | ty::Param(_) @@ -1454,7 +1451,7 @@ impl<'tcx> Ty<'tcx> { false } - ty::Foreign(_) | ty::CoroutineWitness(..) | ty::Error(_) | ty::UnsafeBinder(_) => false, + ty::Foreign(_) | ty::Error(_) | ty::UnsafeBinder(_) => false, } } @@ -1564,7 +1561,6 @@ pub fn needs_drop_components_with_async<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) => Ok(smallvec![ty]), } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index ced9bd735ba2b..44d30e1bb3902 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -161,7 +161,6 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::UnsafeBinder(_) @@ -202,7 +201,6 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | ty::FnDef(_, _) | ty::FnPtr(..) | ty::Dynamic(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::UnsafeBinder(_) | ty::Alias(_, _) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 5254f60a15036..70b22ebe19d9e 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -939,7 +939,7 @@ fn try_write_constant<'tcx>( | ty::Dynamic(..) | ty::UnsafeBinder(_) => throw_machine_stop_str!("unsupported type"), - ty::Error(_) | ty::Infer(..) | ty::CoroutineWitness(..) => bug!(), + ty::Error(_) | ty::Infer(..) => bug!(), } interp_ok(()) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 8dfa875ca6f94..4aac02cef8058 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -391,7 +391,6 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Alias(_, _) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index d27d80a086ad1..c5afcce7344de 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -700,7 +700,6 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Param(_) @@ -818,7 +817,6 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Param(_) 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 05ea217c1de08..10c4f138b692b 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 @@ -75,16 +75,17 @@ where Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()])) } - ty::Coroutine(def_id, args) => Ok(ty::Binder::dummy(vec![ - args.as_coroutine().tupled_upvars_ty(), - Ty::new_coroutine_witness_for_coroutine(ecx.cx(), def_id, args), - ])), - - ty::CoroutineWitness(def_id, args) => Ok(ecx - .cx() - .coroutine_hidden_types(def_id) - .instantiate(cx, args) - .map_bound(|bound| bound.types.to_vec())), + ty::Coroutine(def_id, args) => { + let coroutine = args.as_coroutine(); + Ok(ecx.cx().coroutine_hidden_types(def_id).instantiate(ecx.cx(), args).map_bound( + |bound_tys| { + [coroutine.tupled_upvars_ty()] + .into_iter() + .chain(bound_tys.types.iter()) + .collect() + }, + )) + } ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), @@ -116,7 +117,7 @@ where { match ty.kind() { // impl {Meta,}Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char - // impl {Meta,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine, CoroutineWitness + // impl {Meta,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine // impl {Meta,}Sized for Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) @@ -129,7 +130,6 @@ where | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Pat(..) | ty::Closure(..) @@ -244,10 +244,17 @@ where Movability::Static => Err(NoSolution), Movability::Movable => { if ecx.cx().features().coroutine_clone() { - Ok(ty::Binder::dummy(vec![ - args.as_coroutine().tupled_upvars_ty(), - Ty::new_coroutine_witness_for_coroutine(ecx.cx(), def_id, args), - ])) + let coroutine = args.as_coroutine(); + Ok(ecx + .cx() + .coroutine_hidden_types(def_id) + .instantiate(ecx.cx(), args) + .map_bound(|bound_tys| { + [coroutine.tupled_upvars_ty()] + .into_iter() + .chain(bound_tys.types.iter()) + .collect() + })) } else { Err(NoSolution) } @@ -255,13 +262,6 @@ where }, ty::UnsafeBinder(_) => Err(NoSolution), - - // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types - ty::CoroutineWitness(def_id, args) => Ok(ecx - .cx() - .coroutine_hidden_types(def_id) - .instantiate(ecx.cx(), args) - .map_bound(|bound| bound.types.to_vec())), } } @@ -385,7 +385,6 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( | ty::Ref(_, _, _) | ty::Dynamic(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Pat(_, _) @@ -788,10 +785,7 @@ pub(in crate::solve) fn const_conditions_for_destruct( // Coroutines and closures could implement `[const] Drop`, // but they don't really need to right now. - ty::Closure(_, _) - | ty::CoroutineClosure(_, _) - | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) => Err(NoSolution), + ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) => Err(NoSolution), // FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop` // if their inner type implements it. 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 70c28421c57ea..5e1748e943133 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 @@ -639,7 +639,6 @@ where | ty::CoroutineClosure(..) | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Foreign(..) => Ty::new_unit(cx), @@ -892,7 +891,6 @@ where | ty::CoroutineClosure(..) | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Foreign(..) | ty::Adt(_, _) 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 651f073efb828..92081cddd70e8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -746,8 +746,7 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::UnsafeBinder(_) - | ty::CoroutineWitness(..) => { + | ty::UnsafeBinder(_) => { ecx.add_goal( GoalSource::ImplWhereBound, goal.with( @@ -1249,7 +1248,6 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Adt(_, _) diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index fee920221e1d1..9d7186f41a3b2 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -306,7 +306,6 @@ impl<'tcx, 'a> TypeVisitor> for ExportableItemsChecker<'tcx, 'a> { | ty::FnDef(_, _) | ty::FnPtr(_, _) | ty::CoroutineClosure(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::UnsafeBinder(_) | ty::Alias(ty::AliasTyKind::Opaque, _) => { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 721635ed48ff5..19ccf380f5a5a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -426,7 +426,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { | ty::Alias(_, _) | ty::Param(_) | ty::Error(_) => ConstructorSet::Unlistable, - ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => { + ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => { bug!("Encountered unexpected type in `ConstructorSet::for_ty`: {ty:?}") } }) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 8656ec6e39aed..af28312b3dd2a 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -295,8 +295,7 @@ where | ty::UnsafeBinder(_) | ty::Param(..) | ty::Bound(..) - | ty::Error(_) - | ty::CoroutineWitness(..) => {} + | ty::Error(_) => {} ty::Placeholder(..) | ty::Infer(..) => { bug!("unexpected type: {:?}", ty) } diff --git a/compiler/rustc_public/src/compiler_interface.rs b/compiler/rustc_public/src/compiler_interface.rs index 82ee546c59910..65378024417a4 100644 --- a/compiler/rustc_public/src/compiler_interface.rs +++ b/compiler/rustc_public/src/compiler_interface.rs @@ -57,7 +57,6 @@ impl Bridge for BridgeTys { type ConstDef = crate::ty::ConstDef; type ImplDef = crate::ty::ImplDef; type RegionDef = crate::ty::RegionDef; - type CoroutineWitnessDef = crate::ty::CoroutineWitnessDef; type AssocDef = crate::ty::AssocDef; type OpaqueDef = crate::ty::OpaqueDef; type Prov = crate::ty::Prov; diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 5da79196dd4ed..5bf95331281c4 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -263,7 +263,6 @@ bridge_impl!(GenericDef, crate::ty::GenericDef); bridge_impl!(ConstDef, crate::ty::ConstDef); bridge_impl!(ImplDef, crate::ty::ImplDef); bridge_impl!(RegionDef, crate::ty::RegionDef); -bridge_impl!(CoroutineWitnessDef, crate::ty::CoroutineWitnessDef); bridge_impl!(AssocDef, crate::ty::AssocDef); bridge_impl!(OpaqueDef, crate::ty::OpaqueDef); bridge_impl!(StaticDef, crate::mir::mono::StaticDef); diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 14656a2e594ad..9bec4db155206 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -565,7 +565,6 @@ pub enum RigidTy { Dynamic(Vec>, Region), Never, Tuple(Vec), - CoroutineWitness(CoroutineWitnessDef, GenericArgs), } impl RigidTy { @@ -994,11 +993,6 @@ crate_def! { pub RegionDef; } -crate_def! { - #[derive(Serialize)] - pub CoroutineWitnessDef; -} - /// A list of generic arguments. #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub struct GenericArgs(pub Vec); diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index d9f314a8e29cc..290cb3a0ac7eb 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -184,10 +184,7 @@ impl RustcInternal for RigidTy { def.0.internal(tables, tcx), args.internal(tables, tcx), ), - RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness( - def.0.internal(tables, tcx), - args.internal(tables, tcx), - ), + RigidTy::Dynamic(predicate, region) => rustc_ty::TyKind::Dynamic( tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)), region.internal(tables, tcx), diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index ca8234280be85..e86f2df681e36 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -461,10 +461,6 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { ty::Bound(ty::BoundVarIndexKind::Bound(debruijn_idx), bound_ty) => { TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables, cx)) } - ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness( - tables.coroutine_witness_def(*def_id), - args.stable(tables, cx), - )), ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => { unreachable!(); } diff --git a/compiler/rustc_public/src/visitor.rs b/compiler/rustc_public/src/visitor.rs index acc3334769613..28c93485c3d15 100644 --- a/compiler/rustc_public/src/visitor.rs +++ b/compiler/rustc_public/src/visitor.rs @@ -167,7 +167,6 @@ impl Visitable for RigidTy { RigidTy::Adt(_, args) | RigidTy::Closure(_, args) | RigidTy::Coroutine(_, args) - | RigidTy::CoroutineWitness(_, args) | RigidTy::CoroutineClosure(_, args) | RigidTy::FnDef(_, args) => args.visit(visitor), RigidTy::FnPtr(sig) => sig.visit(visitor), diff --git a/compiler/rustc_public_bridge/src/bridge.rs b/compiler/rustc_public_bridge/src/bridge.rs index d4f4847c8d3bd..044b873682e2f 100644 --- a/compiler/rustc_public_bridge/src/bridge.rs +++ b/compiler/rustc_public_bridge/src/bridge.rs @@ -53,7 +53,6 @@ make_bridge_trait!(GenericDef); make_bridge_trait!(ConstDef); make_bridge_trait!(ImplDef); make_bridge_trait!(RegionDef); -make_bridge_trait!(CoroutineWitnessDef); make_bridge_trait!(AssocDef); make_bridge_trait!(OpaqueDef); make_bridge_trait!(StaticDef); diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index 025ec0e7a8c85..b61cadfbb41d6 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -177,13 +177,6 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> { B::RegionDef::new(self.create_def_id(did)) } - pub fn coroutine_witness_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> B::CoroutineWitnessDef { - B::CoroutineWitnessDef::new(self.create_def_id(did)) - } - pub fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> B::AssocDef { B::AssocDef::new(self.create_def_id(did)) } @@ -230,7 +223,6 @@ pub trait Bridge: Sized { type ConstDef: ConstDef; type ImplDef: ImplDef; type RegionDef: RegionDef; - type CoroutineWitnessDef: CoroutineWitnessDef; type AssocDef: AssocDef; type OpaqueDef: OpaqueDef; type Prov: Prov; diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 5505fe82cea65..dd3eca1ed4280 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -617,12 +617,7 @@ pub(crate) fn encode_ty<'tcx>( } // Unexpected types - ty::Alias(..) - | ty::Bound(..) - | ty::Error(..) - | ty::CoroutineWitness(..) - | ty::Infer(..) - | ty::Placeholder(..) => { + ty::Alias(..) | ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Placeholder(..) => { bug!("encode_ty: unexpected `{:?}`", ty.kind()); } }; diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 9cea681fcb579..566db40c0caa9 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -53,7 +53,6 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { ty::Closure(..) | ty::Coroutine(..) | ty::CoroutineClosure(..) - | ty::CoroutineWitness(..) | ty::Dynamic(..) | ty::Float(..) | ty::FnDef(..) diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 3896e06a627b7..b63e87607a637 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -114,7 +114,6 @@ impl<'tcx> AbiHashStable<'tcx> for Ty<'tcx> { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::Tuple(_) | ty::Alias(_, _) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 755b4923e9cd4..ce869a3485c51 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -588,7 +588,6 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { } ty::Alias(..) => bug!("symbol_names: unexpected alias"), - ty::CoroutineWitness(..) => bug!("symbol_names: unexpected `CoroutineWitness`"), } // Only cache types that do not refer to an enclosing diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 8762607edf5dc..38b0111dd366d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1824,10 +1824,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::Adt(..) => Some(17), ty::Coroutine(..) => Some(18), ty::Foreign(..) => Some(19), - ty::CoroutineWitness(..) => Some(20), - ty::CoroutineClosure(..) => Some(21), - ty::Pat(..) => Some(22), - ty::UnsafeBinder(..) => Some(23), + ty::CoroutineClosure(..) => Some(20), + ty::Pat(..) => Some(21), + ty::UnsafeBinder(..) => Some(22), ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None, } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 81b921b3744f4..0656a237ca882 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2405,7 +2405,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); match *ty.kind() { - ty::Coroutine(did, ..) | ty::CoroutineWitness(did, _) => { + ty::Coroutine(did, ..) => { coroutine = coroutine.or(Some(did)); outer_coroutine = Some(did); } @@ -2434,7 +2434,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); match *ty.kind() { - ty::Coroutine(did, ..) | ty::CoroutineWitness(did, ..) => { + ty::Coroutine(did, ..) => { coroutine = coroutine.or(Some(did)); outer_coroutine = Some(did); } @@ -3458,10 +3458,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )), ); } - ty::CoroutineWitness(..) => { - // Skip printing coroutine-witnesses, since we'll drill into - // the bad field in another derived obligation cause. - } ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) => { err.span_note( tcx.def_span(def_id), diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 66c949a38cea7..f6ed921ef8670 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -474,10 +474,9 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( // Coroutines and closures could implement `[const] Drop`, // but they don't really need to right now. - ty::Closure(_, _) - | ty::CoroutineClosure(_, _) - | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) => return Err(EvaluationFailure::NoSolution), + ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) => { + return Err(EvaluationFailure::NoSolution); + } // FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop` // if their inner type implements it. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e5c2adaa261d3..6462363181fff 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1036,7 +1036,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(..) // Integers and floats always have `u8` as their discriminant. @@ -1091,7 +1090,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never // Extern types have unit metadata, according to RFC 2850 | ty::Foreign(_) diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 2e60805cd10a5..87d6a90017136 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -38,7 +38,6 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::FnDef(..) | ty::FnPtr(..) | ty::Char - | ty::CoroutineWitness(..) | ty::RawPtr(_, _) | ty::Ref(..) | ty::Str @@ -279,8 +278,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( | ty::RawPtr(..) | ty::Ref(..) | ty::FnDef(..) - | ty::FnPtr(..) - | ty::CoroutineWitness(..) => { + | ty::FnPtr(..) => { // these types never have a destructor } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index d0833f0308350..ae3af00366044 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -697,7 +697,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) @@ -853,10 +852,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::CoroutineWitness(..) => { - candidates.vec.push(AutoImplCandidate); - } - ty::Bool | ty::Char | ty::Int(_) @@ -1203,10 +1198,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::CoroutineWitness(..) => { - candidates.vec.push(SizedCandidate); - } - // Fallback to whatever user-defined impls or param-env clauses exist in this case. ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {} @@ -1259,10 +1250,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::CoroutineWitness(..) => { - candidates.vec.push(SizedCandidate); - } - // Conditionally `Sized`. ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => { candidates.vec.push(SizedCandidate); @@ -1335,7 +1322,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Alias(..) | ty::Param(_) @@ -1374,7 +1360,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(..) @@ -1427,7 +1412,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::UnsafeBinder(_) - | ty::CoroutineWitness(..) | ty::Bound(..) => { candidates.vec.push(BikeshedGuaranteedNoDropCandidate); } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4f65b30775ed0..6d804cc6ee5ff 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1311,7 +1311,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::UnsafeBinder(_) - | ty::CoroutineWitness(..) | ty::Bound(..) => { obligations.push(obligation.with( tcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d6c9adfb28177..969f72b1e9fa5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2155,7 +2155,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -2209,12 +2208,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Never | ty::Ref(_, _, hir::Mutability::Not) | ty::Array(..) => { - unreachable!("tried to assemble `Sized` for type with libcore-provided impl") + unreachable!("tried to assemble `Copy`/`Clone` for type with libcore-provided impl") } // FIXME(unsafe_binder): Should we conditionally // (i.e. universally) implement copy/clone? - ty::UnsafeBinder(_) => unreachable!("tried to assemble `Sized` for unsafe binder"), + ty::UnsafeBinder(_) => { + unreachable!("tried to assemble `Copy`/`Clone` for unsafe binder") + } ty::Tuple(tys) => { // (*) binder moved here @@ -2232,10 +2233,17 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } hir::Movability::Movable => { if self.tcx().features().coroutine_clone() { - ty::Binder::dummy(vec![ - args.as_coroutine().tupled_upvars_ty(), - Ty::new_coroutine_witness_for_coroutine(self.tcx(), def_id, args), - ]) + self.infcx + .tcx + .coroutine_hidden_types(def_id) + .instantiate(self.infcx.tcx, args) + .map_bound(|witness| { + args.as_coroutine() + .upvar_tys() + .iter() + .chain(witness.types) + .collect() + }) } else { unreachable!( "tried to assemble `Clone` for coroutine without enabled feature" @@ -2244,13 +2252,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } }, - ty::CoroutineWitness(def_id, args) => self - .infcx - .tcx - .coroutine_hidden_types(def_id) - .instantiate(self.infcx.tcx, args) - .map_bound(|witness| witness.types.to_vec()), - ty::Closure(_, args) => ty::Binder::dummy(args.as_closure().upvar_tys().to_vec()), ty::CoroutineClosure(_, args) => { @@ -2365,24 +2366,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Coroutine(def_id, args) => { let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty()); - let tcx = self.tcx(); - let witness = Ty::new_coroutine_witness_for_coroutine(tcx, def_id, args); - ty::Binder::dummy(AutoImplConstituents { - types: vec![ty, witness], - assumptions: vec![], - }) + self.infcx + .tcx + .coroutine_hidden_types(def_id) + .instantiate(self.infcx.tcx, args) + .map_bound(|witness| AutoImplConstituents { + types: [ty].into_iter().chain(witness.types).collect(), + assumptions: witness.assumptions.to_vec(), + }) } - ty::CoroutineWitness(def_id, args) => self - .infcx - .tcx - .coroutine_hidden_types(def_id) - .instantiate(self.infcx.tcx, args) - .map_bound(|witness| AutoImplConstituents { - types: witness.types.to_vec(), - assumptions: witness.assumptions.to_vec(), - }), - // For `PhantomData`, we pass `T`. ty::Adt(def, args) if def.is_phantom_data() => { ty::Binder::dummy(AutoImplConstituents { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d383cb9d91dd4..5031462c29068 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -729,7 +729,6 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { | ty::Float(..) | ty::Error(_) | ty::Str - | ty::CoroutineWitness(..) | ty::Never | ty::Param(_) | ty::Bound(..) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index cbe15eb54787f..caf7550650e9f 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -262,7 +262,6 @@ fn resolve_associated_item<'tcx>( match self_ty.kind() { ty::FnDef(..) | ty::FnPtr(..) => (), ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Tuple(..) => {} diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 62f3667ad7f4f..5eb9546159da2 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -776,7 +776,7 @@ fn layout_of_uncached<'tcx>( return Err(error(cx, err)); } - ty::Bound(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => { + ty::Bound(..) | ty::Infer(_) | ty::Error(_) => { // `ty::Error` is handled at the top of this function. bug!("layout_of: unexpected type `{ty}`") } diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 0ef435b1a0e21..9f9afbe01b980 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -219,10 +219,6 @@ where return Some(self.always_drop_component(ty)); } } - ty::CoroutineWitness(..) => { - unreachable!("witness should be handled in parent"); - } - ty::UnsafeBinder(bound_ty) => { let ty = self.tcx.instantiate_bound_regions_with_erased(bound_ty.into()); queue_type(self, ty); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index bb25a14ef7443..89551905ef9f7 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -37,7 +37,6 @@ fn sizedness_constraint_for_ty<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never => None, ty::Str | ty::Slice(..) | ty::Dynamic(_, _) => match sizedness { @@ -385,7 +384,6 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::Tuple(_) | ty::Alias(_, _) diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index ed6416a7f55f2..b7c13621e4979 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -42,7 +42,6 @@ pub enum SimplifiedType { Trait(DefId), Closure(DefId), Coroutine(DefId), - CoroutineWitness(DefId), Function(usize), UnsafeBinder, Placeholder, @@ -139,7 +138,6 @@ pub fn simplify_type( ty::Closure(def_id, _) => Some(SimplifiedType::Closure(def_id.into())), ty::CoroutineClosure(def_id, _) => Some(SimplifiedType::Closure(def_id.into())), ty::Coroutine(def_id, _) => Some(SimplifiedType::Coroutine(def_id.into())), - ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id.into())), ty::Never => Some(SimplifiedType::Never), ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())), ty::FnPtr(sig_tys, _hdr) => { @@ -174,8 +172,7 @@ impl SimplifiedType { | SimplifiedType::Foreign(d) | SimplifiedType::Trait(d) | SimplifiedType::Closure(d) - | SimplifiedType::Coroutine(d) - | SimplifiedType::CoroutineWitness(d) => Some(d), + | SimplifiedType::Coroutine(d) => Some(d), _ => None, } } @@ -306,7 +303,6 @@ impl {} @@ -454,13 +450,6 @@ impl false, }, - ty::CoroutineWitness(lhs_def_id, lhs_args) => match rhs.kind() { - ty::CoroutineWitness(rhs_def_id, rhs_args) => { - lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth) - } - _ => false, - }, - ty::Pat(lhs_ty, _) => { // FIXME(pattern_types): take pattern into account matches!(rhs.kind(), ty::Pat(rhs_ty, _) if self.types_may_unify_inner(lhs_ty, rhs_ty, depth)) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 8b057e5866cd9..910dc0c11d913 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -246,9 +246,7 @@ impl FlagComputation { self.add_flags(TypeFlags::HAS_TY_PARAM); } - ty::Closure(_, args) - | ty::CoroutineClosure(_, args) - | ty::CoroutineWitness(_, args) => { + ty::Closure(_, args) | ty::CoroutineClosure(_, args) => { self.add_args(args.as_slice()); } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 4323b1ca64690..05d7062868d63 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -90,14 +90,6 @@ pub trait Ty>: fn new_closure(interner: I, def_id: I::ClosureId, args: I::GenericArgs) -> Self; - fn new_coroutine_witness(interner: I, def_id: I::CoroutineId, args: I::GenericArgs) -> Self; - - fn new_coroutine_witness_for_coroutine( - interner: I, - def_id: I::CoroutineId, - coroutine_args: I::GenericArgs, - ) -> Self; - fn new_ptr(interner: I, ty: Self, mutbl: Mutability) -> Self; fn new_ref(interner: I, region: I::Region, ty: Self, mutbl: Mutability) -> Self; @@ -182,7 +174,6 @@ pub trait Ty>: | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::Tuple(_) | ty::Alias(_, _) diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index c7dccea6adc12..75f729fa846d1 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -126,10 +126,6 @@ impl TypeVisitor for OutlivesCollector<'_, I> { // want these to affect region inference } - // All regions are bound inside a witness, and we don't emit - // higher-ranked outlives components currently. - ty::CoroutineWitness(..) => {} - // OutlivesTypeParameterEnv -- the actual checking that `X:'a` // is implied by the environment is done in regionck. ty::Param(p) => { diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 3610605462ba9..3c95e51646513 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -394,16 +394,6 @@ pub fn structurally_relate_tys>( Ok(Ty::new_coroutine(cx, a_id, args)) } - (ty::CoroutineWitness(a_id, a_args), ty::CoroutineWitness(b_id, b_args)) - if a_id == b_id => - { - // All CoroutineWitness types with the same id represent - // the (anonymous) type of the same coroutine expression. So - // all of their regions should be equated. - let args = relate_args_invariantly(relation, a_args, b_args)?; - Ok(Ty::new_coroutine_witness(cx, a_id, args)) - } - (ty::Closure(a_id, a_args), ty::Closure(b_id, b_args)) if a_id == b_id => { // All Closure types with the same id represent // the (anonymous) type of the same closure expression. So diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 498797bef653a..ffcc1b34463a7 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -178,31 +178,6 @@ pub enum TyKind { /// `CoroutineArgs`. Coroutine(I::CoroutineId, I::GenericArgs), - /// A type representing the types stored inside a coroutine. - /// This should only appear as part of the `CoroutineArgs`. - /// - /// Unlike upvars, the witness can reference lifetimes from - /// inside of the coroutine itself. To deal with them in - /// the type of the coroutine, we convert them to higher ranked - /// lifetimes bound by the witness itself. - /// - /// This contains the `DefId` and the `GenericArgsRef` of the coroutine. - /// The actual witness types are computed on MIR by the `mir_coroutine_witnesses` query. - /// - /// Looking at the following example, the witness for this coroutine - /// may end up as something like `for<'a> [Vec, &'a Vec]`: - /// - /// ``` - /// #![feature(coroutines)] - /// #[coroutine] static |a| { - /// let x = &vec![3]; - /// yield a; - /// yield x[0]; - /// } - /// # ; - /// ``` - CoroutineWitness(I::CoroutineId, I::GenericArgs), - /// The never type `!`. Never, @@ -308,7 +283,6 @@ impl TyKind { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) => true, @@ -361,7 +335,6 @@ impl fmt::Debug for TyKind { Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(), CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(), Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(), - CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(), Never => write!(f, "!"), Tuple(t) => { write!(f, "(")?; diff --git a/compiler/rustc_type_ir/src/walk.rs b/compiler/rustc_type_ir/src/walk.rs index e48d598a5328d..a1b5dace53fd0 100644 --- a/compiler/rustc_type_ir/src/walk.rs +++ b/compiler/rustc_type_ir/src/walk.rs @@ -135,7 +135,6 @@ fn push_inner(stack: &mut TypeWalkerStack, parent: I::GenericArg | ty::Closure(_, args) | ty::CoroutineClosure(_, args) | ty::Coroutine(_, args) - | ty::CoroutineWitness(_, args) | ty::FnDef(_, args) => { stack.extend(args.iter().rev()); } diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs index e2f106e565439..3cc324be13ccf 100644 --- a/tests/debuginfo/function-names.rs +++ b/tests/debuginfo/function-names.rs @@ -85,6 +85,7 @@ use std::ops::Coroutine; use std::pin::Pin; + use Mod1::TestTrait2; fn main() { diff --git a/tests/ui/async-await/partial-drop-partial-reinit.rs b/tests/ui/async-await/partial-drop-partial-reinit.rs index b72552ed32479..436acb220b2e6 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.rs +++ b/tests/ui/async-await/partial-drop-partial-reinit.rs @@ -7,7 +7,6 @@ fn main() { //~^ ERROR cannot be sent between threads safely //~| NOTE cannot be sent //~| NOTE bound introduced by - //~| NOTE appears within the type } fn gimme_send(t: T) { diff --git a/tests/ui/async-await/partial-drop-partial-reinit.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr index cf4b408ad12b8..d167c7ad06971 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr @@ -16,7 +16,7 @@ LL | struct NotSend {} | ^^^^^^^^^^^^^^ = note: required because it appears within the type `(NotSend,)` note: required because it's used within this `async` fn body - --> $DIR/partial-drop-partial-reinit.rs:27:16 + --> $DIR/partial-drop-partial-reinit.rs:26:16 | LL | async fn foo() { | ________________^ @@ -28,7 +28,7 @@ LL | | bar().await; LL | | } | |_^ note: required by a bound in `gimme_send` - --> $DIR/partial-drop-partial-reinit.rs:13:18 + --> $DIR/partial-drop-partial-reinit.rs:12:18 | LL | fn gimme_send(t: T) { | ^^^^ required by this bound in `gimme_send` diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr index a028f4331725e..e6e87d5fedef3 100644 --- a/tests/ui/symbol-names/basic.legacy.stderr +++ b/tests/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17h1dddcfd03744167fE) +error: symbol-name(_ZN5basic4main17h450e807e9148568eE) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::h1dddcfd03744167f) +error: demangling(basic::main::h450e807e9148568e) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr index 14cbd877d9f8a..388a10cc54e64 100644 --- a/tests/ui/symbol-names/issue-60925.legacy.stderr +++ b/tests/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h4b3099ec5dc5d306E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h878706bd4ff1829aE) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo::foo::h4b3099ec5dc5d306) +error: demangling(issue_60925::foo::Foo::foo::h878706bd4ff1829a) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] From 47fb6e7cd743c6ba5595f47917bd52f1dcdc6120 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 18 Jul 2025 20:21:11 +0000 Subject: [PATCH 2/3] Fix tools --- src/librustdoc/clean/mod.rs | 1 - src/librustdoc/passes/collect_intra_doc_links.rs | 1 - src/tools/clippy/clippy_lints/src/dereference.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 597a85f397695..6b4ae03c35430 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2258,7 +2258,6 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::CoroutineClosure(..) => panic!("CoroutineClosure"), ty::Coroutine(..) => panic!("Coroutine"), ty::Placeholder(..) => panic!("Placeholder"), - ty::CoroutineWitness(..) => panic!("CoroutineWitness"), ty::Infer(..) => panic!("Infer"), ty::Error(_) => FatalError.raise(), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 07d6efaa97e15..c1e51939b265f 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -533,7 +533,6 @@ impl<'tcx> LinkCollector<'_, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Dynamic(..) | ty::UnsafeBinder(_) | ty::Param(_) diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 32fd4afb122e6..c7bcc6b32f8c7 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -916,7 +916,6 @@ impl TyCoercionStability { | ty::Foreign(_) | ty::FnDef(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Never From 3b6e09140e61c774cfbf6e9a92dc7d6df997b2b5 Mon Sep 17 00:00:00 2001 From: Emil Dietrich Date: Mon, 12 Jan 2026 20:02:29 +0100 Subject: [PATCH 3/3] rebase fixup --- .../src/const_eval/type_info.rs | 1 - compiler/rustc_lint/src/gpukernel_abi.rs | 1 - compiler/rustc_lint/src/types.rs | 703 ------------------ .../rustc_lint/src/types/improper_ctypes.rs | 1 - compiler/rustc_middle/src/ty/offload_meta.rs | 1 - compiler/rustc_middle/src/ty/print/pretty.rs | 14 - .../rustc_next_trait_solver/src/coherence.rs | 3 +- .../src/traits/effects.rs | 16 +- 8 files changed, 6 insertions(+), 734 deletions(-) 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 f932b198b4260..f9cdc7575fb43 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -75,7 +75,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Never | ty::Alias(..) | ty::Param(_) diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs index dbdf5b6e7955f..3bc4fc8d0b2d1 100644 --- a/compiler/rustc_lint/src/gpukernel_abi.rs +++ b/compiler/rustc_lint/src/gpukernel_abi.rs @@ -122,7 +122,6 @@ impl<'tcx> TypeFolder> for CheckGpuKernelTypes<'tcx> { | ty::Closure(_, _) | ty::Coroutine(_, _) | ty::CoroutineClosure(_, _) - | ty::CoroutineWitness(..) | ty::Dynamic(_, _) | ty::FnDef(_, _) | ty::FnPtr(..) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 4cd34361e5a8b..f3e6db6f2d8e4 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -931,709 +931,6 @@ fn get_nullable_type_from_pat<'tcx>( } } -impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { - /// Check if the type is array and emit an unsafe type lint. - fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { - if let ty::Array(..) = ty.kind() { - self.emit_ffi_unsafe_type_lint( - ty, - sp, - fluent::lint_improper_ctypes_array_reason, - Some(fluent::lint_improper_ctypes_array_help), - ); - true - } else { - false - } - } - - /// Checks if the given field's type is "ffi-safe". - fn check_field_type_for_ffi( - &self, - acc: &mut CTypesVisitorState<'tcx>, - field: &ty::FieldDef, - args: GenericArgsRef<'tcx>, - ) -> FfiResult<'tcx> { - let field_ty = field.ty(self.cx.tcx, args); - let field_ty = self - .cx - .tcx - .try_normalize_erasing_regions(self.cx.typing_env(), field_ty) - .unwrap_or(field_ty); - self.check_type_for_ffi(acc, field_ty) - } - - /// Checks if the given `VariantDef`'s field types are "ffi-safe". - fn check_variant_for_ffi( - &self, - acc: &mut CTypesVisitorState<'tcx>, - ty: Ty<'tcx>, - def: ty::AdtDef<'tcx>, - variant: &ty::VariantDef, - args: GenericArgsRef<'tcx>, - ) -> FfiResult<'tcx> { - use FfiResult::*; - let transparent_with_all_zst_fields = if def.repr().transparent() { - if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { - // Transparent newtypes have at most one non-ZST field which needs to be checked.. - match self.check_field_type_for_ffi(acc, field, args) { - FfiUnsafe { ty, .. } if ty.is_unit() => (), - r => return r, - } - - false - } else { - // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all - // `PhantomData`). - true - } - } else { - false - }; - - // We can't completely trust `repr(C)` markings, so make sure the fields are actually safe. - let mut all_phantom = !variant.fields.is_empty(); - for field in &variant.fields { - all_phantom &= match self.check_field_type_for_ffi(acc, field, args) { - FfiSafe => false, - // `()` fields are FFI-safe! - FfiUnsafe { ty, .. } if ty.is_unit() => false, - FfiPhantom(..) => true, - r @ FfiUnsafe { .. } => return r, - } - } - - if all_phantom { - FfiPhantom(ty) - } else if transparent_with_all_zst_fields { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_struct_zst, help: None } - } else { - FfiSafe - } - } - - /// Checks if the given type is "ffi-safe" (has a stable, well-defined - /// representation which can be exported to C code). - fn check_type_for_ffi( - &self, - acc: &mut CTypesVisitorState<'tcx>, - ty: Ty<'tcx>, - ) -> FfiResult<'tcx> { - use FfiResult::*; - - let tcx = self.cx.tcx; - - // Protect against infinite recursion, for example - // `struct S(*mut S);`. - // FIXME: A recursion limit is necessary as well, for irregular - // recursive types. - if !acc.cache.insert(ty) { - return FfiSafe; - } - - match *ty.kind() { - ty::Adt(def, args) => { - if let Some(boxed) = ty.boxed_ty() - && matches!(self.mode, CItemKind::Definition) - { - if boxed.is_sized(tcx, self.cx.typing_env()) { - return FfiSafe; - } else { - return FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_box, - help: None, - }; - } - } - if def.is_phantom_data() { - return FfiPhantom(ty); - } - match def.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - if let Some(sym::cstring_type | sym::cstr_type) = - tcx.get_diagnostic_name(def.did()) - && !acc.base_ty.is_mutable_ptr() - { - return FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_cstr_reason, - help: Some(fluent::lint_improper_ctypes_cstr_help), - }; - } - - if !def.repr().c() && !def.repr().transparent() { - return FfiUnsafe { - ty, - reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_layout_reason - } else { - fluent::lint_improper_ctypes_union_layout_reason - }, - help: if def.is_struct() { - Some(fluent::lint_improper_ctypes_struct_layout_help) - } else { - Some(fluent::lint_improper_ctypes_union_layout_help) - }, - }; - } - - if def.non_enum_variant().field_list_has_applicable_non_exhaustive() { - return FfiUnsafe { - ty, - reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_non_exhaustive - } else { - fluent::lint_improper_ctypes_union_non_exhaustive - }, - help: None, - }; - } - - if def.non_enum_variant().fields.is_empty() { - return FfiUnsafe { - ty, - reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_fieldless_reason - } else { - fluent::lint_improper_ctypes_union_fieldless_reason - }, - help: if def.is_struct() { - Some(fluent::lint_improper_ctypes_struct_fieldless_help) - } else { - Some(fluent::lint_improper_ctypes_union_fieldless_help) - }, - }; - } - - self.check_variant_for_ffi(acc, ty, def, def.non_enum_variant(), args) - } - AdtKind::Enum => { - if def.variants().is_empty() { - // Empty enums are okay... although sort of useless. - return FfiSafe; - } - // Check for a repr() attribute to specify the size of the - // discriminant. - if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none() - { - // Special-case types like `Option` and `Result` - if let Some(ty) = - repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode) - { - return self.check_type_for_ffi(acc, ty); - } - - return FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_enum_repr_reason, - help: Some(fluent::lint_improper_ctypes_enum_repr_help), - }; - } - - use improper_ctypes::check_non_exhaustive_variant; - - let non_exhaustive = def.variant_list_has_applicable_non_exhaustive(); - // Check the contained variants. - let ret = def.variants().iter().try_for_each(|variant| { - check_non_exhaustive_variant(non_exhaustive, variant) - .map_break(|reason| FfiUnsafe { ty, reason, help: None })?; - - match self.check_variant_for_ffi(acc, ty, def, variant, args) { - FfiSafe => ControlFlow::Continue(()), - r => ControlFlow::Break(r), - } - }); - if let ControlFlow::Break(result) = ret { - return result; - } - - FfiSafe - } - } - } - - ty::Char => FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_char_reason, - help: Some(fluent::lint_improper_ctypes_char_help), - }, - - // It's just extra invariants on the type that you need to uphold, - // but only the base type is relevant for being representable in FFI. - ty::Pat(base, ..) => self.check_type_for_ffi(acc, base), - - // Primitive types with a stable representation. - ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe, - - ty::Slice(_) => FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_slice_reason, - help: Some(fluent::lint_improper_ctypes_slice_help), - }, - - ty::Dynamic(..) => { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_dyn, help: None } - } - - ty::Str => FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_str_reason, - help: Some(fluent::lint_improper_ctypes_str_help), - }, - - ty::Tuple(..) => FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_tuple_reason, - help: Some(fluent::lint_improper_ctypes_tuple_help), - }, - - ty::RawPtr(ty, _) | ty::Ref(_, ty, _) - if { - matches!(self.mode, CItemKind::Definition) - && ty.is_sized(self.cx.tcx, self.cx.typing_env()) - } => - { - FfiSafe - } - - ty::RawPtr(ty, _) - if match ty.kind() { - ty::Tuple(tuple) => tuple.is_empty(), - _ => false, - } => - { - FfiSafe - } - - ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(acc, ty), - - ty::Array(inner_ty, _) => self.check_type_for_ffi(acc, inner_ty), - - ty::FnPtr(sig_tys, hdr) => { - let sig = sig_tys.with(hdr); - if sig.abi().is_rustic_abi() { - return FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_fnptr_reason, - help: Some(fluent::lint_improper_ctypes_fnptr_help), - }; - } - - let sig = tcx.instantiate_bound_regions_with_erased(sig); - for arg in sig.inputs() { - match self.check_type_for_ffi(acc, *arg) { - FfiSafe => {} - r => return r, - } - } - - let ret_ty = sig.output(); - if ret_ty.is_unit() { - return FfiSafe; - } - - self.check_type_for_ffi(acc, ret_ty) - } - - ty::Foreign(..) => FfiSafe, - - // While opaque types are checked for earlier, if a projection in a struct field - // normalizes to an opaque type, then it will reach this branch. - ty::Alias(ty::Opaque, ..) => { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_opaque, help: None } - } - - // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, - // so they are currently ignored for the purposes of this lint. - ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent, ..) - if matches!(self.mode, CItemKind::Definition) => - { - FfiSafe - } - - ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), - - ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) - | ty::Infer(..) - | ty::Bound(..) - | ty::Error(_) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::Placeholder(..) - | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty), - } - } - - fn emit_ffi_unsafe_type_lint( - &mut self, - ty: Ty<'tcx>, - sp: Span, - note: DiagMessage, - help: Option, - ) { - let lint = match self.mode { - CItemKind::Declaration => IMPROPER_CTYPES, - CItemKind::Definition => IMPROPER_CTYPES_DEFINITIONS, - }; - let desc = match self.mode { - CItemKind::Declaration => "block", - CItemKind::Definition => "fn", - }; - let span_note = if let ty::Adt(def, _) = ty.kind() - && let Some(sp) = self.cx.tcx.hir_span_if_local(def.did()) - { - Some(sp) - } else { - None - }; - self.cx.emit_span_lint( - lint, - sp, - ImproperCTypes { ty, desc, label: sp, help, note, span_note }, - ); - } - - fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { - struct ProhibitOpaqueTypes; - impl<'tcx> ty::TypeVisitor> for ProhibitOpaqueTypes { - type Result = ControlFlow>; - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - if !ty.has_opaque_types() { - return ControlFlow::Continue(()); - } - - if let ty::Alias(ty::Opaque, ..) = ty.kind() { - ControlFlow::Break(ty) - } else { - ty.super_visit_with(self) - } - } - } - - if let Some(ty) = self - .cx - .tcx - .try_normalize_erasing_regions(self.cx.typing_env(), ty) - .unwrap_or(ty) - .visit_with(&mut ProhibitOpaqueTypes) - .break_value() - { - self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint_improper_ctypes_opaque, None); - true - } else { - false - } - } - - fn check_type_for_ffi_and_report_errors( - &mut self, - sp: Span, - ty: Ty<'tcx>, - is_static: bool, - is_return_type: bool, - ) { - if self.check_for_opaque_ty(sp, ty) { - // We've already emitted an error due to an opaque type. - return; - } - - let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty); - - // C doesn't really support passing arrays by value - the only way to pass an array by value - // is through a struct. So, first test that the top level isn't an array, and then - // recursively check the types inside. - if !is_static && self.check_for_array_ty(sp, ty) { - return; - } - - // Don't report FFI errors for unit return types. This check exists here, and not in - // the caller (where it would make more sense) so that normalization has definitely - // happened. - if is_return_type && ty.is_unit() { - return; - } - - let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty }; - match self.check_type_for_ffi(&mut acc, ty) { - FfiResult::FfiSafe => {} - FfiResult::FfiPhantom(ty) => { - self.emit_ffi_unsafe_type_lint( - ty, - sp, - fluent::lint_improper_ctypes_only_phantomdata, - None, - ); - } - FfiResult::FfiUnsafe { ty, reason, help } => { - self.emit_ffi_unsafe_type_lint(ty, sp, reason, help); - } - } - } - - /// Check if a function's argument types and result type are "ffi-safe". - /// - /// For a external ABI function, argument types and the result type are walked to find fn-ptr - /// types that have external ABIs, as these still need checked. - fn check_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) { - let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity(); - let sig = self.cx.tcx.instantiate_bound_regions_with_erased(sig); - - for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { - for (fn_ptr_ty, span) in self.find_fn_ptr_ty_with_external_abi(input_hir, *input_ty) { - self.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, false, false); - } - } - - if let hir::FnRetTy::Return(ret_hir) = decl.output { - for (fn_ptr_ty, span) in self.find_fn_ptr_ty_with_external_abi(ret_hir, sig.output()) { - self.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, false, true); - } - } - } - - /// Check if a function's argument types and result type are "ffi-safe". - fn check_foreign_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) { - let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity(); - let sig = self.cx.tcx.instantiate_bound_regions_with_erased(sig); - - for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { - self.check_type_for_ffi_and_report_errors(input_hir.span, *input_ty, false, false); - } - - if let hir::FnRetTy::Return(ret_hir) = decl.output { - self.check_type_for_ffi_and_report_errors(ret_hir.span, sig.output(), false, true); - } - } - - fn check_foreign_static(&mut self, id: hir::OwnerId, span: Span) { - let ty = self.cx.tcx.type_of(id).instantiate_identity(); - self.check_type_for_ffi_and_report_errors(span, ty, true, false); - } - - /// Find any fn-ptr types with external ABIs in `ty`. - /// - /// For example, `Option` returns `extern "C" fn()` - fn find_fn_ptr_ty_with_external_abi( - &self, - hir_ty: &hir::Ty<'tcx>, - ty: Ty<'tcx>, - ) -> Vec<(Ty<'tcx>, Span)> { - struct FnPtrFinder<'tcx> { - spans: Vec, - tys: Vec>, - } - - impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> { - fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) { - debug!(?ty); - if let hir::TyKind::FnPtr(hir::FnPtrTy { abi, .. }) = ty.kind - && !abi.is_rustic_abi() - { - self.spans.push(ty.span); - } - - hir::intravisit::walk_ty(self, ty) - } - } - - impl<'tcx> ty::TypeVisitor> for FnPtrFinder<'tcx> { - type Result = (); - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - if let ty::FnPtr(_, hdr) = ty.kind() - && !hdr.abi.is_rustic_abi() - { - self.tys.push(ty); - } - - ty.super_visit_with(self) - } - } - - let mut visitor = FnPtrFinder { spans: Vec::new(), tys: Vec::new() }; - ty.visit_with(&mut visitor); - visitor.visit_ty_unambig(hir_ty); - - iter::zip(visitor.tys.drain(..), visitor.spans.drain(..)).collect() - } -} - -impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { - fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { - let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; - let abi = cx.tcx.hir_get_foreign_abi(it.hir_id()); - - match it.kind { - hir::ForeignItemKind::Fn(sig, _, _) => { - if abi.is_rustic_abi() { - vis.check_fn(it.owner_id.def_id, sig.decl) - } else { - vis.check_foreign_fn(it.owner_id.def_id, sig.decl); - } - } - hir::ForeignItemKind::Static(ty, _, _) if !abi.is_rustic_abi() => { - vis.check_foreign_static(it.owner_id, ty.span); - } - hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (), - } - } -} - -impl ImproperCTypesDefinitions { - fn check_ty_maybe_containing_foreign_fnptr<'tcx>( - &mut self, - cx: &LateContext<'tcx>, - hir_ty: &'tcx hir::Ty<'_>, - ty: Ty<'tcx>, - ) { - let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; - for (fn_ptr_ty, span) in vis.find_fn_ptr_ty_with_external_abi(hir_ty, ty) { - vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false); - } - } - - fn check_arg_for_power_alignment<'tcx>( - &mut self, - cx: &LateContext<'tcx>, - ty: Ty<'tcx>, - ) -> bool { - assert!(cx.tcx.sess.target.os == "aix"); - // Structs (under repr(C)) follow the power alignment rule if: - // - the first field of the struct is a floating-point type that - // is greater than 4-bytes, or - // - the first field of the struct is an aggregate whose - // recursively first field is a floating-point type greater than - // 4 bytes. - if ty.is_floating_point() && ty.primitive_size(cx.tcx).bytes() > 4 { - return true; - } else if let Adt(adt_def, _) = ty.kind() - && adt_def.is_struct() - && adt_def.repr().c() - && !adt_def.repr().packed() - && adt_def.repr().align.is_none() - { - let struct_variant = adt_def.variant(VariantIdx::ZERO); - // Within a nested struct, all fields are examined to correctly - // report if any fields after the nested struct within the - // original struct are misaligned. - for struct_field in &struct_variant.fields { - let field_ty = cx.tcx.type_of(struct_field.did).instantiate_identity(); - if self.check_arg_for_power_alignment(cx, field_ty) { - return true; - } - } - } - return false; - } - - fn check_struct_for_power_alignment<'tcx>( - &mut self, - cx: &LateContext<'tcx>, - item: &'tcx hir::Item<'tcx>, - ) { - let adt_def = cx.tcx.adt_def(item.owner_id.to_def_id()); - // repr(C) structs also with packed or aligned representation - // should be ignored. - if adt_def.repr().c() - && !adt_def.repr().packed() - && adt_def.repr().align.is_none() - && cx.tcx.sess.target.os == "aix" - && !adt_def.all_fields().next().is_none() - { - let struct_variant_data = item.expect_struct().2; - for field_def in struct_variant_data.fields().iter().skip(1) { - // Struct fields (after the first field) are checked for the - // power alignment rule, as fields after the first are likely - // to be the fields that are misaligned. - let def_id = field_def.def_id; - let ty = cx.tcx.type_of(def_id).instantiate_identity(); - if self.check_arg_for_power_alignment(cx, ty) { - cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment); - } - } - } - } -} - -/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in -/// `extern "C" { }` blocks): -/// -/// - `extern "" fn` definitions are checked in the same way as the -/// `ImproperCtypesDeclarations` visitor checks functions if `` is external (e.g. "C"). -/// - All other items which contain types (e.g. other functions, struct definitions, etc) are -/// checked for extern fn-ptrs with external ABIs. -impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { - match item.kind { - hir::ItemKind::Static(_, _, ty, _) - | hir::ItemKind::Const(_, _, ty, _) - | hir::ItemKind::TyAlias(_, _, ty) => { - self.check_ty_maybe_containing_foreign_fnptr( - cx, - ty, - cx.tcx.type_of(item.owner_id).instantiate_identity(), - ); - } - // See `check_fn`.. - hir::ItemKind::Fn { .. } => {} - // Structs are checked based on if they follow the power alignment - // rule (under repr(C)). - hir::ItemKind::Struct(..) => { - self.check_struct_for_power_alignment(cx, item); - } - // See `check_field_def`.. - hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {} - // Doesn't define something that can contain a external type to be checked. - hir::ItemKind::Impl(..) - | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::Trait(..) - | hir::ItemKind::GlobalAsm { .. } - | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Mod(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::Use(..) - | hir::ItemKind::ExternCrate(..) => {} - } - } - - fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'tcx>) { - self.check_ty_maybe_containing_foreign_fnptr( - cx, - field.ty, - cx.tcx.type_of(field.def_id).instantiate_identity(), - ); - } - - fn check_fn( - &mut self, - cx: &LateContext<'tcx>, - kind: hir::intravisit::FnKind<'tcx>, - decl: &'tcx hir::FnDecl<'_>, - _: &'tcx hir::Body<'_>, - _: Span, - id: LocalDefId, - ) { - use hir::intravisit::FnKind; - - let abi = match kind { - FnKind::ItemFn(_, _, header, ..) => header.abi, - FnKind::Method(_, sig, ..) => sig.header.abi, - _ => return, - }; - - let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; - if abi.is_rustic_abi() { - vis.check_fn(id, decl); - } else { - vis.check_foreign_fn(id, decl); - } - } -} - declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 38094c67c34a0..e716af3add7f6 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -681,7 +681,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Placeholder(..) | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty), } diff --git a/compiler/rustc_middle/src/ty/offload_meta.rs b/compiler/rustc_middle/src/ty/offload_meta.rs index 04a7cd2c75f28..b917fe9201726 100644 --- a/compiler/rustc_middle/src/ty/offload_meta.rs +++ b/compiler/rustc_middle/src/ty/offload_meta.rs @@ -104,7 +104,6 @@ impl MappingFlags { | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) | ty::Never | ty::Bound(_, _) | ty::Placeholder(_) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ac12706995cd7..f1d1fb818aab1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1001,7 +1001,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(did, args)?; } } else { -<<<<<<< HEAD self.print_def_path(did, args)?; write!(self, " closure_kind_ty=")?; args.as_coroutine_closure().kind_ty().print(self)?; @@ -1011,19 +1010,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { args.as_coroutine_closure().tupled_upvars_ty().print(self)?; write!(self, " coroutine_captures_by_ref_ty=")?; args.as_coroutine_closure().coroutine_captures_by_ref_ty().print(self)?; -======= - p!(print_def_path(did, args)); - p!( - " closure_kind_ty=", - print(args.as_coroutine_closure().kind_ty()), - " signature_parts_ty=", - print(args.as_coroutine_closure().signature_parts_ty()), - " upvar_tys=", - print(args.as_coroutine_closure().tupled_upvars_ty()), - " coroutine_captures_by_ref_ty=", - print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()) - ); ->>>>>>> 3995d8bfb2b (Remove coroutine witness type) } write!(self, "}}")?; } diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index c370fd24a1bb3..6b7cf224aa424 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -437,8 +437,7 @@ where ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) => { + | ty::Coroutine(..) => { unreachable!("unnameable type in coherence: {ty:?}"); } }; diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index f6ed921ef8670..1db3a8b37ce94 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -8,7 +8,7 @@ use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::elaborate::elaborate; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, Ty, TypingMode}; +use rustc_middle::ty::{self, TypingMode}; use thin_vec::{ThinVec, thin_vec}; use super::SelectionContext; @@ -382,10 +382,10 @@ fn evaluate_host_effect_for_copy_clone_goal<'tcx>( ty::Movability::Static => Err(EvaluationFailure::NoSolution), ty::Movability::Movable => { if tcx.features().coroutine_clone() { - Ok(ty::Binder::dummy(vec![ - args.as_coroutine().tupled_upvars_ty(), - Ty::new_coroutine_witness_for_coroutine(tcx, def_id, args), - ])) + Ok(tcx + .coroutine_hidden_types(def_id) + .instantiate(tcx, args) + .map_bound(|bound| bound.types.to_vec())) } else { Err(EvaluationFailure::NoSolution) } @@ -394,12 +394,6 @@ fn evaluate_host_effect_for_copy_clone_goal<'tcx>( } ty::UnsafeBinder(_) => Err(EvaluationFailure::NoSolution), - - // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types - ty::CoroutineWitness(def_id, args) => Ok(tcx - .coroutine_hidden_types(def_id) - .instantiate(tcx, args) - .map_bound(|bound| bound.types.to_vec())), }?; Ok(constituent_tys