diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 57d939747aa..d4cde7e2c65 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -781,8 +781,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { ); return; } - Ok(Some(ImplSource::Closure(data))) => { - if !tcx.is_const_fn_raw(data.closure_def_id) { + Ok(Some(ImplSource::Closure(_))) => { + let ty::Closure(closure_def_id, substs) = + *poly_trait_pred.self_ty().no_bound_vars().unwrap().kind() + else { + unreachable!() + }; + if !tcx.is_const_fn_raw(closure_def_id) { self.check_op(ops::FnCallNonConst { caller, callee, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a39f3ae7b4d..98179c0f933 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -664,16 +664,16 @@ pub enum ImplSource<'tcx, N> { /// ImplSource automatically generated for a closure. The `DefId` is the ID /// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the /// impl is generated by the compiler and does not appear in the source. - Closure(ImplSourceClosureData<'tcx, N>), + Closure(Vec), /// Same as above, but for a function pointer type with the given signature. - FnPointer(ImplSourceFnPointerData<'tcx, N>), + FnPointer(Vec), /// ImplSource automatically generated for a generator. - Generator(ImplSourceGeneratorData<'tcx, N>), + Generator(Vec), /// ImplSource automatically generated for a generator backing an async future. - Future(ImplSourceFutureData<'tcx, N>), + Future(Vec), /// ImplSource for a trait alias. TraitAlias(ImplSourceTraitAliasData<'tcx, N>), @@ -683,12 +683,13 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { ImplSource::UserDefined(i) => i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, - ImplSource::Closure(c) => c.nested, - ImplSource::Generator(c) => c.nested, - ImplSource::Future(c) => c.nested, + ImplSource::Param(n, _) + | ImplSource::Builtin(n) + | ImplSource::FnPointer(n) + | ImplSource::Closure(n) + | ImplSource::Generator(n) + | ImplSource::Future(n) => n, ImplSource::Object(d) => d.nested, - ImplSource::FnPointer(d) => d.nested, ImplSource::TraitAlias(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested, } @@ -697,12 +698,13 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn borrow_nested_obligations(&self) -> &[N] { match self { ImplSource::UserDefined(i) => &i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, - ImplSource::Closure(c) => &c.nested, - ImplSource::Generator(c) => &c.nested, - ImplSource::Future(c) => &c.nested, + ImplSource::Param(n, _) + | ImplSource::Builtin(n) + | ImplSource::FnPointer(n) + | ImplSource::Closure(n) + | ImplSource::Generator(n) + | ImplSource::Future(n) => &n, ImplSource::Object(d) => &d.nested, - ImplSource::FnPointer(d) => &d.nested, ImplSource::TraitAlias(d) => &d.nested, ImplSource::TraitUpcasting(d) => &d.nested, } @@ -711,12 +713,13 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] { match self { ImplSource::UserDefined(i) => &mut i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, - ImplSource::Closure(c) => &mut c.nested, - ImplSource::Generator(c) => &mut c.nested, - ImplSource::Future(c) => &mut c.nested, + ImplSource::Param(n, _) + | ImplSource::Builtin(n) + | ImplSource::FnPointer(n) + | ImplSource::Closure(n) + | ImplSource::Generator(n) + | ImplSource::Future(n) => n, ImplSource::Object(d) => &mut d.nested, - ImplSource::FnPointer(d) => &mut d.nested, ImplSource::TraitAlias(d) => &mut d.nested, ImplSource::TraitUpcasting(d) => &mut d.nested, } @@ -739,25 +742,10 @@ impl<'tcx, N> ImplSource<'tcx, N> { vtable_base: o.vtable_base, nested: o.nested.into_iter().map(f).collect(), }), - ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData { - closure_def_id: c.closure_def_id, - substs: c.substs, - nested: c.nested.into_iter().map(f).collect(), - }), - ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData { - generator_def_id: c.generator_def_id, - substs: c.substs, - nested: c.nested.into_iter().map(f).collect(), - }), - ImplSource::Future(c) => ImplSource::Future(ImplSourceFutureData { - generator_def_id: c.generator_def_id, - substs: c.substs, - nested: c.nested.into_iter().map(f).collect(), - }), - ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData { - fn_ty: p.fn_ty, - nested: p.nested.into_iter().map(f).collect(), - }), + ImplSource::Closure(n) => ImplSource::Closure(n.into_iter().map(f).collect()), + ImplSource::Generator(n) => ImplSource::Generator(n.into_iter().map(f).collect()), + ImplSource::Future(n) => ImplSource::Future(n.into_iter().map(f).collect()), + ImplSource::FnPointer(n) => ImplSource::FnPointer(n.into_iter().map(f).collect()), ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData { alias_def_id: d.alias_def_id, substs: d.substs, @@ -791,36 +779,6 @@ pub struct ImplSourceUserDefinedData<'tcx, N> { pub nested: Vec, } -#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceGeneratorData<'tcx, N> { - pub generator_def_id: DefId, - pub substs: SubstsRef<'tcx>, - /// Nested obligations. This can be non-empty if the generator - /// signature contains associated types. - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceFutureData<'tcx, N> { - pub generator_def_id: DefId, - pub substs: SubstsRef<'tcx>, - /// Nested obligations. This can be non-empty if the generator - /// signature contains associated types. - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceClosureData<'tcx, N> { - pub closure_def_id: DefId, - pub substs: SubstsRef<'tcx>, - /// Nested obligations. This can be non-empty if the closure - /// signature contains associated types. - pub nested: Vec, -} - #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] #[derive(TypeFoldable, TypeVisitable)] pub struct ImplSourceTraitUpcastingData { @@ -848,13 +806,6 @@ pub struct ImplSourceObjectData { pub nested: Vec, } -#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceFnPointerData<'tcx, N> { - pub fn_ty: Ty<'tcx>, - pub nested: Vec, -} - #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] #[derive(TypeFoldable, TypeVisitable)] pub struct ImplSourceTraitAliasData<'tcx, N> { diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index 3e7ed4dabe9..bc0e656a656 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -42,36 +42,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx, } } -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceGeneratorData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "ImplSourceGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})", - self.generator_def_id, self.substs, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFutureData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "ImplSourceFutureData(generator_def_id={:?}, substs={:?}, nested={:?})", - self.generator_def_id, self.substs, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceClosureData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "ImplSourceClosureData(closure_def_id={:?}, substs={:?}, nested={:?})", - self.closure_def_id, self.substs, self.nested - ) - } -} - impl fmt::Debug for traits::ImplSourceTraitUpcastingData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -92,12 +62,6 @@ impl fmt::Debug for traits::ImplSourceObjectData { } } -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFnPointerData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ImplSourceFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested) - } -} - impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index f82885252b7..1477c8957f6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -3,6 +3,7 @@ use super::specialization_graph; use super::translate_substs; use super::util; +use super::ImplSourceUserDefinedData; use super::MismatchedProjectionTypes; use super::Obligation; use super::ObligationCause; @@ -10,10 +11,6 @@ use super::PredicateObligation; use super::Selection; use super::SelectionContext; use super::SelectionError; -use super::{ - ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData, - ImplSourceUserDefinedData, -}; use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; use crate::errors::InherentProjectionNormalizationOverflow; @@ -2015,9 +2012,14 @@ fn confirm_select_candidate<'cx, 'tcx>( fn confirm_generator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - impl_source: ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>, + nested: Vec>, ) -> Progress<'tcx> { - let gen_sig = impl_source.substs.as_generator().poly_sig(); + let ty::Generator(_, substs, _) = + selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() + else { + unreachable!() + }; + let gen_sig = substs.as_generator().poly_sig(); let Normalized { value: gen_sig, obligations } = normalize_with_depth( selcx, obligation.param_env, @@ -2055,16 +2057,21 @@ fn confirm_generator_candidate<'cx, 'tcx>( }); confirm_param_env_candidate(selcx, obligation, predicate, false) - .with_addl_obligations(impl_source.nested) + .with_addl_obligations(nested) .with_addl_obligations(obligations) } fn confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - impl_source: ImplSourceFutureData<'tcx, PredicateObligation<'tcx>>, + nested: Vec>, ) -> Progress<'tcx> { - let gen_sig = impl_source.substs.as_generator().poly_sig(); + let ty::Generator(_, substs, _) = + selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() + else { + unreachable!() + }; + let gen_sig = substs.as_generator().poly_sig(); let Normalized { value: gen_sig, obligations } = normalize_with_depth( selcx, obligation.param_env, @@ -2094,7 +2101,7 @@ fn confirm_future_candidate<'cx, 'tcx>( }); confirm_param_env_candidate(selcx, obligation, predicate, false) - .with_addl_obligations(impl_source.nested) + .with_addl_obligations(nested) .with_addl_obligations(obligations) } @@ -2155,9 +2162,9 @@ fn confirm_builtin_candidate<'cx, 'tcx>( fn confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - fn_pointer_impl_source: ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>, + nested: Vec>, ) -> Progress<'tcx> { - let fn_type = selcx.infcx.shallow_resolve(fn_pointer_impl_source.fn_ty); + let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let sig = fn_type.fn_sig(selcx.tcx()); let Normalized { value: sig, obligations } = normalize_with_depth( selcx, @@ -2168,16 +2175,21 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( ); confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes) - .with_addl_obligations(fn_pointer_impl_source.nested) + .with_addl_obligations(nested) .with_addl_obligations(obligations) } fn confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - impl_source: ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, + nested: Vec>, ) -> Progress<'tcx> { - let closure_sig = impl_source.substs.as_closure().sig(); + let ty::Closure(_, substs) = + selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() + else { + unreachable!() + }; + let closure_sig = substs.as_closure().sig(); let Normalized { value: closure_sig, obligations } = normalize_with_depth( selcx, obligation.param_env, @@ -2189,7 +2201,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate"); confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No) - .with_addl_obligations(impl_source.nested) + .with_addl_obligations(nested) .with_addl_obligations(obligations) } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index bf37cc68b8c..d369a087c9b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -27,7 +27,6 @@ use crate::traits::vtable::{ }; use crate::traits::{ BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, - ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, @@ -664,8 +663,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, is_const: bool, - ) -> Result>, SelectionError<'tcx>> - { + ) -> Result>, SelectionError<'tcx>> { debug!(?obligation, "confirm_fn_pointer_candidate"); let tcx = self.tcx(); @@ -717,7 +715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]); nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr)); - Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested }) + Ok(nested) } fn confirm_trait_alias_candidate( @@ -749,8 +747,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_generator_candidate( &mut self, obligation: &TraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> - { + ) -> Result>, SelectionError<'tcx>> { // Okay to skip binder because the substs on generator types never // touch bound regions, they just capture the in-scope // type/region parameters. @@ -783,13 +780,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; debug!(?trait_ref, ?nested, "generator candidate obligations"); - Ok(ImplSourceGeneratorData { generator_def_id, substs, nested }) + Ok(nested) } fn confirm_future_candidate( &mut self, obligation: &TraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result>, SelectionError<'tcx>> { // Okay to skip binder because the substs on generator types never // touch bound regions, they just capture the in-scope // type/region parameters. @@ -813,14 +810,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; debug!(?trait_ref, ?nested, "future candidate obligations"); - Ok(ImplSourceFutureData { generator_def_id, substs, nested }) + Ok(nested) } #[instrument(skip(self), level = "debug")] fn confirm_closure_candidate( &mut self, obligation: &TraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result>, SelectionError<'tcx>> { let kind = self .tcx() .fn_trait_kind_from_def_id(obligation.predicate.def_id()) @@ -847,7 +844,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { )); } - Ok(ImplSourceClosureData { closure_def_id, substs, nested }) + Ok(nested) } /// In the case of closure types and fn pointers, diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 81ad883903f..cc7700f378a 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -177,30 +177,30 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } - traits::ImplSource::Generator(generator_data) => { + traits::ImplSource::Generator(_) => { + let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else { + unreachable!() + }; if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume { // For compiler developers who'd like to add new items to `Generator`, // you either need to generate a shim body, or perhaps return // `InstanceDef::Item` pointing to a trait default method body if // it is given a default implementation by the trait. span_bug!( - tcx.def_span(generator_data.generator_def_id), + tcx.def_span(generator_def_id), "no definition for `{trait_ref}::{}` for built-in generator type", tcx.item_name(trait_item_id) ) } - Some(Instance { - def: ty::InstanceDef::Item(generator_data.generator_def_id), - substs: generator_data.substs, - }) + Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs }) } - traits::ImplSource::Future(future_data) => { + traits::ImplSource::Future(_) => { + let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else { + unreachable!() + }; if Some(trait_item_id) == tcx.lang_items().future_poll_fn() { // `Future::poll` is generated by the compiler. - Some(Instance { - def: ty::InstanceDef::Item(future_data.generator_def_id), - substs: future_data.substs, - }) + Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs }) } else { // All other methods are default methods of the `Future` trait. // (this assumes that `ImplSource::Future` is only used for methods on `Future`) @@ -208,7 +208,10 @@ fn resolve_associated_item<'tcx>( Some(Instance::new(trait_item_id, rcvr_substs)) } } - traits::ImplSource::Closure(closure_data) => { + traits::ImplSource::Closure(_) => { + let ty::Closure(closure_def_id, substs) = *rcvr_substs.type_at(0).kind() else { + unreachable!() + }; if cfg!(debug_assertions) && ![sym::call, sym::call_mut, sym::call_once] .contains(&tcx.item_name(trait_item_id)) @@ -218,20 +221,15 @@ fn resolve_associated_item<'tcx>( // `InstanceDef::Item` pointing to a trait default method body if // it is given a default implementation by the trait. span_bug!( - tcx.def_span(closure_data.closure_def_id), + tcx.def_span(closure_def_id), "no definition for `{trait_ref}::{}` for built-in closure type", tcx.item_name(trait_item_id) ) } let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap(); - Instance::resolve_closure( - tcx, - closure_data.closure_def_id, - closure_data.substs, - trait_closure_kind, - ) + Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind) } - traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() { + traits::ImplSource::FnPointer(_) => match rcvr_substs.type_at(0).kind() { ty::FnDef(..) | ty::FnPtr(..) => { if cfg!(debug_assertions) && ![sym::call, sym::call_mut, sym::call_once] @@ -247,7 +245,7 @@ fn resolve_associated_item<'tcx>( ) } Some(Instance { - def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty), + def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)), substs: rcvr_substs, }) }