diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 58829f72a72f0..ee46930a433f3 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1779,7 +1779,7 @@ impl<'tcx> Ty<'tcx> { } } - /// Fast path helper for testing if a type is `Sized` or `MetaSized`. + /// Fast path helper for testing if a type is `Sized`, `MetaSized` or `PointeeSized`. /// /// Returning true means the type is known to implement the sizedness trait. Returning `false` /// means nothing -- could be sized, might not be. @@ -1814,11 +1814,12 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { SizedTraitKind::Sized => false, - SizedTraitKind::MetaSized => true, + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => true, }, ty::Foreign(..) => match sizedness { SizedTraitKind::Sized | SizedTraitKind::MetaSized => false, + SizedTraitKind::PointeeSized => true, }, ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)), 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 a300558c0c9ce..e732a916fcb60 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -476,7 +476,11 @@ where G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::MetaSized) } Some(TraitSolverLangItem::PointeeSized) => { - unreachable!("`PointeeSized` is removed during lowering"); + G::consider_builtin_sizedness_candidates( + self, + goal, + SizedTraitKind::PointeeSized, + ) } Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) 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 f39d32260093c..cc33c920a0969 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 @@ -115,9 +115,9 @@ where I: Interner, { 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 Closure, CoroutineClosure + // impl {Meta,Pointee,}Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char + // impl {Meta,Pointee,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine, CoroutineWitness + // impl {Meta,Pointee,}Sized for Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) | ty::Int(_) @@ -138,14 +138,19 @@ where | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), - // impl {Meta,}Sized for str, [T], dyn Trait + // impl {Meta,Pointee,}Sized for str, [T], dyn Trait ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { SizedTraitKind::Sized => Err(NoSolution), - SizedTraitKind::MetaSized => Ok(ty::Binder::dummy(vec![])), + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => { + Ok(ty::Binder::dummy(vec![])) + } }, - // impl {} for extern type - ty::Foreign(..) => Err(NoSolution), + // impl PointeeSized for extern type + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Err(NoSolution), + SizedTraitKind::PointeeSized => Ok(ty::Binder::dummy(vec![])), + }, ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => Err(NoSolution), @@ -156,17 +161,17 @@ where ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), - // impl {Meta,}Sized for () - // impl {Meta,}Sized for (T1, T2, .., Tn) where Tn: {Meta,}Sized if n >= 1 + // impl {Meta,Pointee,}Sized for () + // impl {Meta,Pointee,}Sized for (T1, T2, .., Tn) where Tn: {Meta,}Sized if n >= 1 ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))), - // impl {Meta,}Sized for Adt + // impl {Meta,Pointee,}Sized for Adt // where {meta,pointee,}sized_constraint(Adt): {Meta,}Sized // // `{meta,pointee,}sized_constraint(Adt)` is the deepest struct trail that can be // determined by the definition of `Adt`, independent of the generic args. // - // impl {Meta,}Sized for Adt + // impl {Meta,Pointee,}Sized for Adt // if {meta,pointee,}sized_constraint(Adt) == None // // As a performance optimization, `{meta,pointee,}sized_constraint(Adt)` can return `None` diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 39f115ce0cd56..7b5e638ac3616 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -201,7 +201,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // begin with in those cases. if matches!( self.tcx.as_lang_item(trait_pred.def_id()), - Some(LangItem::Sized | LangItem::MetaSized) + Some(LangItem::Sized | LangItem::MetaSized | LangItem::PointeeSized) ) { match self.tainted_by_errors() { None => { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index b247c2c2968b9..3e15ae47b8cb8 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -90,6 +90,13 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< { return Some(Certainty::Yes); } + Some(LangItem::PointeeSized) + if self + .resolve_vars_if_possible(trait_pred.self_ty().skip_binder()) + .has_trivial_sizedness(self.0.tcx, SizedTraitKind::PointeeSized) => + { + return Some(Certainty::Yes); + } Some(LangItem::Copy | LangItem::Clone) => { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder()); 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 81ce58a93fa9d..1f6dec3a09aa1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -101,7 +101,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } Some(LangItem::PointeeSized) => { - bug!("`PointeeSized` is removed during lowering"); + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::PointeeSized, + ); } Some(LangItem::Unsize) => { self.assemble_candidates_for_unsizing(obligation, &mut candidates); @@ -1113,7 +1117,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself. + /// Assembles the `Sized`, `MetaSized` and `PointeeSized` traits which are built-in to the + /// language itself. #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_sized_candidate( &mut self, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 80f71c78993cc..5a750aaeabd44 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -270,7 +270,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.sizedness_conditions(obligation, SizedTraitKind::MetaSized) } Some(LangItem::PointeeSized) => { - bug!("`PointeeSized` is removing during lowering"); + self.sizedness_conditions(obligation, SizedTraitKind::PointeeSized) } Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation), Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9c0ccb26e53f6..3efb95c96399f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2129,10 +2129,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { SizedTraitKind::Sized => None, - SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())), + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => { + Where(ty::Binder::dummy(Vec::new())) + } }, - ty::Foreign(..) => None, + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => None, + SizedTraitKind::PointeeSized => Where(ty::Binder::dummy(Vec::new())), + }, ty::Tuple(tys) => Where( obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a05bae535663d..5095f0e4a45f1 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -374,6 +374,7 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc let sizedness = match tcx.as_lang_item(trait_ref.def_id()) { Some(LangItem::Sized) => SizedTraitKind::Sized, Some(LangItem::MetaSized) => SizedTraitKind::MetaSized, + Some(LangItem::PointeeSized) => SizedTraitKind::PointeeSized, _ => return false, }; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index d996ee2b60aa4..9ec3256fcf5cd 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -23,7 +23,7 @@ fn sizedness_constraint_for_ty<'tcx>( ty: Ty<'tcx>, ) -> Option> { match ty.kind() { - // Always `Sized` or `MetaSized` + // Always `{Meta,Pointee,}Sized` ty::Bool | ty::Char | ty::Int(..) @@ -44,11 +44,11 @@ fn sizedness_constraint_for_ty<'tcx>( ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { // Never `Sized` SizedTraitKind::Sized => Some(ty), - // Always `MetaSized` - SizedTraitKind::MetaSized => None, + // Always `{Meta,Pointee}Sized` + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => None, }, - // Maybe `Sized` or `MetaSized` + // Maybe `{Meta,Pointee,}Sized` ty::Param(..) | ty::Alias(..) | ty::Error(_) => Some(ty), // We cannot instantiate the binder, so just return the *original* type back, @@ -58,8 +58,11 @@ fn sizedness_constraint_for_ty<'tcx>( sizedness_constraint_for_ty(tcx, sizedness, inner_ty.skip_binder()).map(|_| ty) } - // Never `MetaSized` or `Sized` - ty::Foreign(..) => Some(ty), + // Never `{Meta,}Sized` + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Some(ty), + SizedTraitKind::PointeeSized => None, + }, // Recursive cases ty::Pat(ty, _) => sizedness_constraint_for_ty(tcx, sizedness, *ty), diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index bbbeaa29f84aa..19039487dc8ff 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -377,6 +377,8 @@ pub enum SizedTraitKind { Sized, /// `MetaSized` trait MetaSized, + /// `PointeeSized` trait + PointeeSized, } impl SizedTraitKind { @@ -385,6 +387,7 @@ impl SizedTraitKind { cx.require_lang_item(match self { SizedTraitKind::Sized => TraitSolverLangItem::Sized, SizedTraitKind::MetaSized => TraitSolverLangItem::MetaSized, + SizedTraitKind::PointeeSized => TraitSolverLangItem::PointeeSized, }) } } diff --git a/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652-1.rs b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652-1.rs new file mode 100644 index 0000000000000..3a2026ffe02e2 --- /dev/null +++ b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652-1.rs @@ -0,0 +1,12 @@ +//@ check-pass +#![feature(sized_hierarchy)] + +use std::marker::PointeeSized; + +type Foo = dyn PointeeSized; + +fn foo(f: &Foo) {} + +fn main() { + foo(&()); +} diff --git a/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.rs b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.rs new file mode 100644 index 0000000000000..31f3287601cac --- /dev/null +++ b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.rs @@ -0,0 +1,9 @@ +#![feature(sized_hierarchy)] + +use std::marker::PointeeSized; + +fn main() { + let x = main; + let y: Box = x; +//~^ ERROR mismatched types +} diff --git a/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.stderr b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.stderr new file mode 100644 index 0000000000000..401712bc55f56 --- /dev/null +++ b/tests/ui/sized-hierarchy/dyn-pointeesized-issue-142652.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/dyn-pointeesized-issue-142652.rs:7:38 + | +LL | let y: Box = x; + | --------------------- ^ expected `Box`, found fn item + | | + | expected due to this + | + = note: expected struct `Box` + found fn item `fn() {main}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | let y: Box = Box::new(x); + | +++++++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.