diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8d1c7c77bb6..24e49ff648f 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -121,7 +121,6 @@ pub fn unadjusted_abi_align(self) -> Align { /// /// Currently, that means that the type is pointer-sized, pointer-aligned, /// and has a initialized (non-union), scalar ABI. - // Please also update compiler/rustc_trait_selection/src/solve/trait_goals.rs if the criteria changes pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool { self.size() == data_layout.pointer_size && self.align().abi == data_layout.pointer_align.abi diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index af533d8db71..2bfb86b592b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -120,6 +120,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ty: Ty<'tcx>, ) -> Result>>, NoSolution> { match *ty.kind() { + // impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, ! + // impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) | ty::Int(_) @@ -152,8 +154,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( bug!("unexpected type `{ty}`") } + // impl Sized for (T1, T2, .., Tn) where T1: Sized, T2: Sized, .. Tn: Sized ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()), + // impl Sized for Adt where T: Sized forall T in field types ty::Adt(def, args) => { let sized_crit = def.sized_constraint(ecx.tcx()); Ok(sized_crit.iter_instantiated(ecx.tcx(), args).map(ty::Binder::dummy).collect()) @@ -167,6 +171,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ty: Ty<'tcx>, ) -> Result>>, NoSolution> { match *ty.kind() { + // impl Copy/Clone for FnDef, FnPtr ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Ok(vec![]), // Implementations are provided in core @@ -196,12 +201,16 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( bug!("unexpected type `{ty}`") } + // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()), + // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), ty::CoroutineClosure(..) => Err(NoSolution), + // only when `coroutine_clone` is enabled and the coroutine is movable + // impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses) ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) { Movability::Static => Err(NoSolution), Movability::Movable => { @@ -217,6 +226,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( } }, + // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types ty::CoroutineWitness(def_id, args) => Ok(ecx .tcx() .coroutine_hidden_types(def_id) diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 9c2a02a5717..ff3fd84af8b 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -188,16 +188,6 @@ fn consider_trait_alias_candidate( }) } - /// ```rust,ignore (not valid rust syntax) - /// impl Sized for u*, i*, bool, f*, FnPtr, FnDef, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, ! - /// - /// impl Sized for (T1, T2, .., Tn) where T1: Sized, T2: Sized, .. Tn: Sized - /// - /// impl Sized for Adt where T: Sized forall T in field types - /// ``` - /// - /// note that `[T; N]` is unconditionally sized since `T: Sized` is required for the array type to be - /// well-formed. fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, @@ -212,20 +202,6 @@ fn consider_builtin_sized_candidate( ) } - /// ```rust,ignore (not valid rust syntax) - /// impl Copy/Clone for FnDef, FnPtr - /// - /// impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone - /// - /// impl Copy/Clone for Closure where T: Copy/Clone forall T in upvars - /// - /// // only when `coroutine_clone` is enabled and the coroutine is movable - /// impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses) - /// - /// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types - /// ``` - /// - /// Some built-in types don't have built-in impls because they can be implemented within the standard library. fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, @@ -240,9 +216,6 @@ fn consider_builtin_copy_clone_candidate( ) } - /// Implements `PointerLike` for types that are pointer-sized, pointer-aligned, - /// and have a initialized (non-union), scalar ABI. - // Please also update compiler/rustc_target/src/abi/mod.rs if the criteria changes fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, @@ -272,18 +245,13 @@ fn consider_builtin_pointer_like_candidate( } } - /// ```rust,ignore (not valid rust syntax) - /// impl FnPtr for FnPtr {} - /// impl !FnPtr for T where T != FnPtr && T is rigid {} - /// ``` - /// - /// Note: see [`Ty::is_known_rigid`] for what it means for the type to be rigid. fn consider_builtin_fn_ptr_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { let self_ty = goal.predicate.self_ty(); match goal.predicate.polarity { + // impl FnPtr for FnPtr {} ty::ImplPolarity::Positive => { if self_ty.is_fn_ptr() { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) @@ -291,6 +259,7 @@ fn consider_builtin_fn_ptr_trait_candidate( Err(NoSolution) } } + // impl !FnPtr for T where T != FnPtr && T is rigid {} ty::ImplPolarity::Negative => { // If a type is rigid and not a fn ptr, then we know for certain // that it does *not* implement `FnPtr`.